|  | /* | 
|  | * Licensed to the Apache Software Foundation (ASF) under one | 
|  | * or more contributor license agreements. See the NOTICE file | 
|  | * distributed with this work for additional information | 
|  | * regarding copyright ownership. The ASF licenses this file | 
|  | * to you under the Apache License, Version 2.0 (the | 
|  | * "License"); you may not use this file except in compliance | 
|  | * with the License. You may obtain a copy of the License at | 
|  | * | 
|  | *   http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, | 
|  | * software distributed under the License is distributed on an | 
|  | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
|  | * KIND, either express or implied. See the License for the | 
|  | * specific language governing permissions and limitations | 
|  | * under the License. | 
|  | */ | 
|  |  | 
|  | // Distributed under the Thrift Software License | 
|  | // | 
|  | // See accompanying file LICENSE or visit the Thrift site at: | 
|  | // http://developers.facebook.com/thrift/ | 
|  | using System; | 
|  | using System.Collections.Generic; | 
|  | using System.Security.Cryptography.X509Certificates; | 
|  | using Thrift.Collections; | 
|  | using Thrift.Test; //generated code | 
|  | using Thrift.Transport; | 
|  | using Thrift.Protocol; | 
|  | using Thrift.Server; | 
|  | using Thrift; | 
|  | using System.Threading; | 
|  | using System.Text; | 
|  | using System.Security.Authentication; | 
|  |  | 
|  | namespace Test | 
|  | { | 
|  | public class TestServer | 
|  | { | 
|  | public static int _clientID = -1; | 
|  | public delegate void TestLogDelegate(string msg, params object[] values); | 
|  |  | 
|  | public class TradeServerEventHandler : TServerEventHandler | 
|  | { | 
|  | public int callCount = 0; | 
|  | public void preServe() | 
|  | { | 
|  | callCount++; | 
|  | } | 
|  | public Object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output) | 
|  | { | 
|  | callCount++; | 
|  | return null; | 
|  | } | 
|  | public void deleteContext(Object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output) | 
|  | { | 
|  | callCount++; | 
|  | } | 
|  | public void processContext(Object serverContext, Thrift.Transport.TTransport transport) | 
|  | { | 
|  | callCount++; | 
|  | } | 
|  | }; | 
|  |  | 
|  | public class TestHandler : ThriftTest.Iface, Thrift.TControllingHandler | 
|  | { | 
|  | public TServer server { get; set; } | 
|  | private int handlerID; | 
|  | private StringBuilder reusableStringBuilder = new StringBuilder(); | 
|  | private TestLogDelegate testLogDelegate; | 
|  |  | 
|  | public TestHandler() | 
|  | { | 
|  | handlerID = Interlocked.Increment(ref _clientID); | 
|  | testLogDelegate += testConsoleLogger; | 
|  | testLogDelegate.Invoke("New TestHandler instance created"); | 
|  | } | 
|  |  | 
|  | public void testConsoleLogger(string msg, params object[] values) | 
|  | { | 
|  | reusableStringBuilder.Clear(); | 
|  | reusableStringBuilder.AppendFormat("handler{0:D3}:",handlerID); | 
|  | reusableStringBuilder.AppendFormat(msg, values); | 
|  | reusableStringBuilder.AppendLine(); | 
|  | Console.Write( reusableStringBuilder.ToString() ); | 
|  | } | 
|  |  | 
|  | public void testVoid() | 
|  | { | 
|  | testLogDelegate.Invoke("testVoid()"); | 
|  | } | 
|  |  | 
|  | public string testString(string thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testString({0})", thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public bool testBool(bool thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testBool({0})", thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public sbyte testByte(sbyte thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testByte({0})", thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public int testI32(int thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testI32({0})", thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public long testI64(long thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testI64({0})", thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public double testDouble(double thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testDouble({0})", thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public byte[] testBinary(byte[] thing) | 
|  | { | 
|  | string hex = BitConverter.ToString(thing).Replace("-", string.Empty); | 
|  | testLogDelegate.Invoke("testBinary({0:X})", hex); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public Xtruct testStruct(Xtruct thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing.String_thing, thing.Byte_thing, thing.I32_thing, thing.I64_thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public Xtruct2 testNest(Xtruct2 nest) | 
|  | { | 
|  | Xtruct thing = nest.Struct_thing; | 
|  | testLogDelegate.Invoke("testNest({{{0}, {{\"{1}\", {2}, {3}, {4}, {5}}}}})", | 
|  | nest.Byte_thing, | 
|  | thing.String_thing, | 
|  | thing.Byte_thing, | 
|  | thing.I32_thing, | 
|  | thing.I64_thing, | 
|  | nest.I32_thing); | 
|  | return nest; | 
|  | } | 
|  |  | 
|  | public Dictionary<int, int> testMap(Dictionary<int, int> thing) | 
|  | { | 
|  | reusableStringBuilder.Clear(); | 
|  | reusableStringBuilder.Append("testMap({{"); | 
|  | bool first = true; | 
|  | foreach (int key in thing.Keys) | 
|  | { | 
|  | if (first) | 
|  | { | 
|  | first = false; | 
|  | } | 
|  | else | 
|  | { | 
|  | reusableStringBuilder.Append(", "); | 
|  | } | 
|  | reusableStringBuilder.AppendFormat("{0} => {1}", key, thing[key]); | 
|  | } | 
|  | reusableStringBuilder.Append("}})"); | 
|  | testLogDelegate.Invoke(reusableStringBuilder.ToString()); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public Dictionary<string, string> testStringMap(Dictionary<string, string> thing) | 
|  | { | 
|  | reusableStringBuilder.Clear(); | 
|  | reusableStringBuilder.Append("testStringMap({{"); | 
|  | bool first = true; | 
|  | foreach (string key in thing.Keys) | 
|  | { | 
|  | if (first) | 
|  | { | 
|  | first = false; | 
|  | } | 
|  | else | 
|  | { | 
|  | reusableStringBuilder.Append(", "); | 
|  | } | 
|  | reusableStringBuilder.AppendFormat("{0} => {1}", key, thing[key]); | 
|  | } | 
|  | reusableStringBuilder.Append("}})"); | 
|  | testLogDelegate.Invoke(reusableStringBuilder.ToString()); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public THashSet<int> testSet(THashSet<int> thing) | 
|  | { | 
|  | reusableStringBuilder.Clear(); | 
|  | reusableStringBuilder.Append("testSet({{"); | 
|  | bool first = true; | 
|  | foreach (int elem in thing) | 
|  | { | 
|  | if (first) | 
|  | { | 
|  | first = false; | 
|  | } | 
|  | else | 
|  | { | 
|  | reusableStringBuilder.Append(", "); | 
|  | } | 
|  | reusableStringBuilder.AppendFormat("{0}", elem); | 
|  | } | 
|  | reusableStringBuilder.Append("}})"); | 
|  | testLogDelegate.Invoke(reusableStringBuilder.ToString()); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public List<int> testList(List<int> thing) | 
|  | { | 
|  | reusableStringBuilder.Clear(); | 
|  | reusableStringBuilder.Append("testList({{"); | 
|  | bool first = true; | 
|  | foreach (int elem in thing) | 
|  | { | 
|  | if (first) | 
|  | { | 
|  | first = false; | 
|  | } | 
|  | else | 
|  | { | 
|  | reusableStringBuilder.Append(", "); | 
|  | } | 
|  | reusableStringBuilder.AppendFormat("{0}", elem); | 
|  | } | 
|  | reusableStringBuilder.Append("}})"); | 
|  | testLogDelegate.Invoke(reusableStringBuilder.ToString()); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public Numberz testEnum(Numberz thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testEnum({0})", thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public long testTypedef(long thing) | 
|  | { | 
|  | testLogDelegate.Invoke("testTypedef({0})", thing); | 
|  | return thing; | 
|  | } | 
|  |  | 
|  | public Dictionary<int, Dictionary<int, int>> testMapMap(int hello) | 
|  | { | 
|  | testLogDelegate.Invoke("testMapMap({0})", hello); | 
|  | Dictionary<int, Dictionary<int, int>> mapmap = | 
|  | new Dictionary<int, Dictionary<int, int>>(); | 
|  |  | 
|  | Dictionary<int, int> pos = new Dictionary<int, int>(); | 
|  | Dictionary<int, int> neg = new Dictionary<int, int>(); | 
|  | for (int i = 1; i < 5; i++) | 
|  | { | 
|  | pos[i] = i; | 
|  | neg[-i] = -i; | 
|  | } | 
|  |  | 
|  | mapmap[4] = pos; | 
|  | mapmap[-4] = neg; | 
|  |  | 
|  | return mapmap; | 
|  | } | 
|  |  | 
|  | // Insanity | 
|  | // returns: | 
|  | // { 1 => { 2 => argument, | 
|  | //          3 => argument, | 
|  | //        }, | 
|  | //   2 => { 6 => <empty Insanity struct>, }, | 
|  | // } | 
|  | public Dictionary<long, Dictionary<Numberz, Insanity>> testInsanity(Insanity argument) | 
|  | { | 
|  | testLogDelegate.Invoke("testInsanity()"); | 
|  |  | 
|  | Dictionary<Numberz, Insanity> first_map = new Dictionary<Numberz, Insanity>(); | 
|  | Dictionary<Numberz, Insanity> second_map = new Dictionary<Numberz, Insanity>(); ; | 
|  |  | 
|  | first_map[Numberz.TWO] = argument; | 
|  | first_map[Numberz.THREE] = argument; | 
|  |  | 
|  | second_map[Numberz.SIX] = new Insanity(); | 
|  |  | 
|  | Dictionary<long, Dictionary<Numberz, Insanity>> insane = | 
|  | new Dictionary<long, Dictionary<Numberz, Insanity>>(); | 
|  | insane[(long)1] = first_map; | 
|  | insane[(long)2] = second_map; | 
|  |  | 
|  | return insane; | 
|  | } | 
|  |  | 
|  | public Xtruct testMulti(sbyte arg0, int arg1, long arg2, Dictionary<short, string> arg3, Numberz arg4, long arg5) | 
|  | { | 
|  | testLogDelegate.Invoke("testMulti()"); | 
|  |  | 
|  | Xtruct hello = new Xtruct(); ; | 
|  | hello.String_thing = "Hello2"; | 
|  | hello.Byte_thing = arg0; | 
|  | hello.I32_thing = arg1; | 
|  | hello.I64_thing = arg2; | 
|  | return hello; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Print 'testException(%s)' with arg as '%s' | 
|  | * @param string arg - a string indication what type of exception to throw | 
|  | * if arg == "Xception" throw Xception with errorCode = 1001 and message = arg | 
|  | * elsen if arg == "TException" throw TException | 
|  | * else do not throw anything | 
|  | */ | 
|  | public void testException(string arg) | 
|  | { | 
|  | testLogDelegate.Invoke("testException({0})", arg); | 
|  | if (arg == "Xception") | 
|  | { | 
|  | Xception x = new Xception(); | 
|  | x.ErrorCode = 1001; | 
|  | x.Message = arg; | 
|  | throw x; | 
|  | } | 
|  | if (arg == "TException") | 
|  | { | 
|  | throw new Thrift.TException(); | 
|  | } | 
|  | return; | 
|  | } | 
|  |  | 
|  | public Xtruct testMultiException(string arg0, string arg1) | 
|  | { | 
|  | testLogDelegate.Invoke("testMultiException({0}, {1})", arg0,arg1); | 
|  | if (arg0 == "Xception") | 
|  | { | 
|  | Xception x = new Xception(); | 
|  | x.ErrorCode = 1001; | 
|  | x.Message = "This is an Xception"; | 
|  | throw x; | 
|  | } | 
|  | else if (arg0 == "Xception2") | 
|  | { | 
|  | Xception2 x = new Xception2(); | 
|  | x.ErrorCode = 2002; | 
|  | x.Struct_thing = new Xtruct(); | 
|  | x.Struct_thing.String_thing = "This is an Xception2"; | 
|  | throw x; | 
|  | } | 
|  |  | 
|  | Xtruct result = new Xtruct(); | 
|  | result.String_thing = arg1; | 
|  | return result; | 
|  | } | 
|  |  | 
|  | public void testStop() | 
|  | { | 
|  | if (server != null) | 
|  | { | 
|  | server.Stop(); | 
|  | } | 
|  | } | 
|  |  | 
|  | public void testOneway(int arg) | 
|  | { | 
|  | testLogDelegate.Invoke("testOneway({0}), sleeping...", arg); | 
|  | System.Threading.Thread.Sleep(arg * 1000); | 
|  | testLogDelegate.Invoke("testOneway finished"); | 
|  | } | 
|  |  | 
|  | } // class TestHandler | 
|  |  | 
|  | private enum ServerType | 
|  | { | 
|  | TSimpleServer, | 
|  | TThreadedServer, | 
|  | TThreadPoolServer, | 
|  | } | 
|  |  | 
|  | private enum ProcessorFactoryType | 
|  | { | 
|  | TSingletonProcessorFactory, | 
|  | TPrototypeProcessorFactory, | 
|  | } | 
|  |  | 
|  | public static bool Execute(string[] args) | 
|  | { | 
|  | try | 
|  | { | 
|  | bool useBufferedSockets = false, useFramed = false, useEncryption = false, compact = false, json = false; | 
|  | ServerType serverType = ServerType.TSimpleServer; | 
|  | ProcessorFactoryType processorFactoryType = ProcessorFactoryType.TSingletonProcessorFactory; | 
|  | int port = 9090; | 
|  | string pipe = null; | 
|  | for (int i = 0; i < args.Length; i++) | 
|  | { | 
|  | if (args[i] == "-pipe")  // -pipe name | 
|  | { | 
|  | pipe = args[++i]; | 
|  | } | 
|  | else if (args[i].Contains("--port=")) | 
|  | { | 
|  | port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1)); | 
|  | } | 
|  | else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered") | 
|  | { | 
|  | useBufferedSockets = true; | 
|  | } | 
|  | else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed") | 
|  | { | 
|  | useFramed = true; | 
|  | } | 
|  | else if (args[i] == "--compact" || args[i] == "--protocol=compact") | 
|  | { | 
|  | compact = true; | 
|  | } | 
|  | else if (args[i] == "--json" || args[i] == "--protocol=json") | 
|  | { | 
|  | json = true; | 
|  | } | 
|  | else if (args[i] == "--threaded" || args[i] == "--server-type=threaded") | 
|  | { | 
|  | serverType = ServerType.TThreadedServer; | 
|  | } | 
|  | else if (args[i] == "--threadpool" || args[i] == "--server-type=threadpool") | 
|  | { | 
|  | serverType = ServerType.TThreadPoolServer; | 
|  | } | 
|  | else if (args[i] == "--prototype" || args[i] == "--processor=prototype") | 
|  | { | 
|  | processorFactoryType = ProcessorFactoryType.TPrototypeProcessorFactory; | 
|  | } | 
|  | else if (args[i] == "--ssl") | 
|  | { | 
|  | useEncryption = true; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Transport | 
|  | TServerTransport trans; | 
|  | if (pipe != null) | 
|  | { | 
|  | trans = new TNamedPipeServerTransport(pipe); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (useEncryption) | 
|  | { | 
|  | string certPath = "../keys/server.p12"; | 
|  | trans = new TTLSServerSocket(port, 0, useBufferedSockets, new X509Certificate2(certPath, "thrift"), null, null, SslProtocols.Tls); | 
|  | } | 
|  | else | 
|  | { | 
|  | trans = new TServerSocket(port, 0, useBufferedSockets); | 
|  | } | 
|  | } | 
|  |  | 
|  | TProtocolFactory proto; | 
|  | if (compact) | 
|  | proto = new TCompactProtocol.Factory(); | 
|  | else if (json) | 
|  | proto = new TJSONProtocol.Factory(); | 
|  | else | 
|  | proto = new TBinaryProtocol.Factory(); | 
|  |  | 
|  | TProcessorFactory processorFactory; | 
|  | if (processorFactoryType == ProcessorFactoryType.TPrototypeProcessorFactory) | 
|  | { | 
|  | processorFactory = new TPrototypeProcessorFactory<ThriftTest.Processor, TestHandler>(); | 
|  | } | 
|  | else | 
|  | { | 
|  | // Processor | 
|  | TestHandler testHandler = new TestHandler(); | 
|  | ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); | 
|  | processorFactory = new TSingletonProcessorFactory(testProcessor); | 
|  | } | 
|  |  | 
|  | TTransportFactory transFactory; | 
|  | if (useFramed) | 
|  | transFactory = new TFramedTransport.Factory(); | 
|  | else | 
|  | transFactory = new TTransportFactory(); | 
|  |  | 
|  | TServer serverEngine; | 
|  | switch (serverType) | 
|  | { | 
|  | case ServerType.TThreadPoolServer: | 
|  | serverEngine = new TThreadPoolServer(processorFactory, trans, transFactory, proto); | 
|  | break; | 
|  | case ServerType.TThreadedServer: | 
|  | serverEngine = new TThreadedServer(processorFactory, trans, transFactory, proto); | 
|  | break; | 
|  | default: | 
|  | serverEngine = new TSimpleServer(processorFactory, trans, transFactory, proto); | 
|  | break; | 
|  | } | 
|  |  | 
|  | //Server event handler | 
|  | TradeServerEventHandler serverEvents = new TradeServerEventHandler(); | 
|  | serverEngine.setEventHandler(serverEvents); | 
|  |  | 
|  | // Run it | 
|  | string where = (pipe != null ? "on pipe " + pipe : "on port " + port); | 
|  | Console.WriteLine("Starting the " + serverType.ToString() + " " + where + | 
|  | (processorFactoryType == ProcessorFactoryType.TPrototypeProcessorFactory ? " with processor prototype factory " : "") + | 
|  | (useBufferedSockets ? " with buffered socket" : "") + | 
|  | (useFramed ? " with framed transport" : "") + | 
|  | (useEncryption ? " with encryption" : "") + | 
|  | (compact ? " with compact protocol" : "") + | 
|  | (json ? " with json protocol" : "") + | 
|  | "..."); | 
|  | serverEngine.Serve(); | 
|  |  | 
|  | } | 
|  | catch (Exception x) | 
|  | { | 
|  | Console.Error.Write(x); | 
|  | return false; | 
|  | } | 
|  | Console.WriteLine("done."); | 
|  | return true; | 
|  | } | 
|  | } | 
|  | } |