/// <summary> /// Stores the result of the routine implementation to the output pipe. /// </summary> /// <param name="result">The result to store</param> private void SetResult(TR result) { Log(LogLevel.Debug, $"Storing Result {result.ToString()}"); byte[] data = ThriftSerializer.Serialize(result); OutPipe.Store(data.Length); OutPipe.Store(data); }
static void ThriftSerializeV11(ThriftCloudEventV11 ev, Stream stream) { using (var sw = new BinaryWriter(stream, Encoding.UTF8, true)) { sw.Write(ThriftSerializer.Serialize(ev)); sw.Flush(); } }
public void Set_Message() { var houseDto = GetHouseDto(); var bodyStream = ThriftSerializer.Serialize(houseDto); var message = new Message(bodyStream); var thriftMessage = new ThriftMessage <HouseDto>(message); thriftMessage.BodyStream.ShouldNotBe(null); }
public void TestSimpleStruct() { SimpleStruct obj1 = CreateSimpleStructWithData(); ThriftSerializer ser = new ThriftSerializer(); byte[] objectBytes = ser.Serialize(obj1); SimpleStruct obj2 = ser.Deserialize <SimpleStruct>(objectBytes); Assert.False(Object.ReferenceEquals(obj1, obj2)); Assert.Equal(obj1, obj2); }
public void TestSturctWithAttributedConstuctor(String a, int b) { StructWithConstructor obj1 = new StructWithConstructor(a, b); ThriftSerializer ser = new ThriftSerializer(); byte[] objectBytes = ser.Serialize(obj1); StructWithConstructor obj2 = ser.Deserialize <StructWithConstructor>(objectBytes); Assert.False(Object.ReferenceEquals(obj1, obj2)); Assert.Equal(obj1, obj2); }
public void TestSimpleStructArray() { var obj1 = CreateSimpleStructWithData(); var obj2 = CreateSimpleStructWithData(); var ser = new ThriftSerializer(); byte[] objectBytes = ser.Serialize(new[] { obj1, obj2 }); var objs = ser.Deserialize <SimpleStruct[]>(objectBytes); Assert.False(Object.ReferenceEquals(objs[0], obj1)); Assert.False(Object.ReferenceEquals(objs[1], obj2)); Assert.Equal(objs[0], obj1); Assert.Equal(objs[1], obj2); }
public void Set_Message_And_Properties() { var houseDto = GetHouseDto(); var properties = new Dictionary <string, object>() { { "whatever", 1 } }; string sessionId = Guid.NewGuid().ToString(); string label = Guid.NewGuid().ToString(); var bodyStream = ThriftSerializer.Serialize(houseDto); var message = new Message(bodyStream, sessionId, label, properties); var thriftMessage = new ThriftMessage <HouseDto>(message); thriftMessage.Label.ShouldBe(label); thriftMessage.SessionId.ShouldBe(sessionId); thriftMessage.Label.ShouldBe(label); AssertProperties(thriftMessage, properties); }
/// <inheritdoc /> protected override void RunRoutine() { try { Log(LogLevel.Debug, "Try to receive result from ObjectiveRoutine"); // Receive object from inPipe InPipe.ReadInt(); T t = InPipe.Read(Activator.CreateInstance <T>()); Log(LogLevel.Debug, $"Received from ObjectiveRoutine: {t.ToString()}"); // Map function List <Tuple <string, TV> > tuples = Map(t); Log(LogLevel.Debug, $"Mapping done, created {tuples.Count} tuples"); // Tell Receiver the number of tuples Log(LogLevel.Debug, "Storing number of tuples"); OutPipe.Store(tuples.Count); // Store tuples to outPipe int i = 1; foreach (Tuple <string, TV> tuple in tuples) { // Write key Log(LogLevel.Debug, $"Write key {i}: {tuple.Item1}"); OutPipe.Store(tuple.Item1); // Write value (size & data) Log(LogLevel.Debug, $"Write value {i}: {tuple.Item2.ToString()}"); byte[] data = ThriftSerializer.Serialize(tuple.Item2); OutPipe.Store(data.Length); // size OutPipe.Store(data); i++; } } catch (Exception e) { Log(LogLevel.Error, $"Error while running map routine: {e.Message}"); throw new RoutineException(e); } }
public ArraySegment <byte> TransformToArraySegment(T value) { var payload = ThriftSerializer.Serialize(value); return(new ArraySegment <byte>(payload)); }
/// <summary> /// Invokes the specified message. /// </summary> /// <param name="message">The message.</param> /// <returns>IMessage.</returns> public override IMessage Invoke(IMessage message) { var mcm = (IMethodCallMessage)message; IMethodReturnMessage returnMessage = null; if (mcm.MethodBase.IsDefined(typeof(ThriftSOperationAttribute), false) == false) { throw new ThriftSException(string.Format("Missing ThriftSOperationAttribute in '{0}.{1}'.", this.ServiceName, mcm.MethodName)); } object returnValue = null; var stopwatch = new Stopwatch(); string invokeDesc = string.Format("调用{0}契约的{1}方法", this.ServiceName, mcm.MethodName); // 构造请求 var srequest = new ThriftSRequest() { ServiceName = this.ServiceName, MethodName = Utils.GetMethodName((MethodInfo)mcm.MethodBase), Headers = new Dictionary <string, string>(), Parameters = new List <ThriftSParameter>() }; srequest.Uri = string.Format("thrift://{0}:{1}/{2}/{3}", this.Host, this.Port, this.ServiceShortName, srequest.MethodName); srequest.Version = Utils.Version; srequest.ClientPid = this.ClientPid; srequest.ClientHostName = this.ClientHostName; srequest.ClientRuntime = ".NET " + Environment.Version.ToString(); try { // 计时开始 stopwatch.Start(); if (mcm.Args != null) { for (var i = 0; i < mcm.Args.Length; i++) { var argument = mcm.Args[i]; ThriftSParameter parameter = null; if (argument == null) { parameter = new ThriftSParameter() { Index = (sbyte)i, Name = string.Empty, Type = string.Empty, Compression = ThriftSCompression.None, ContentType = ContentTypes.Binary, HasValue = false }; } else { parameter = new ThriftSParameter() { Index = (sbyte)i, Name = string.Empty, Type = string.Empty, Compression = ThriftSCompression.None, ContentType = ContentTypes.Thrift, HasValue = true, Value = ThriftSerializer.Serialize(argument) }; } // 大于10K开启压缩 if (parameter.Value != null && parameter.Value.Length > 10 * 1024) { parameter.Value = Utils.GzipCompress(parameter.Value); parameter.Compression = ThriftSCompression.Gzip; } srequest.Parameters.Add(parameter); } } ThriftSResponse sresponse = null; try { var xpool = ConnectionPoolManager.GetPool(this.Host, this.Port, this.Timeout); ThriftSConnection xconnection = null; TimeSpan connectTookTime = TimeSpan.MinValue; try { DateTime beginConnectTime = DateTime.Now; xconnection = xpool.Borrow(); connectTookTime = beginConnectTime - DateTime.Now; if (string.IsNullOrEmpty(this.ClientIP)) { this.ClientIP = xconnection.LocalAddress.ToString(); } srequest.ClientIP = this.ClientIP; sresponse = xconnection.Client.Process(srequest); } catch (SocketException exception) { xpool.ReportError(xconnection, exception); this.HandleException("SocketException", invokeDesc, srequest, exception); } catch (IOException exception) { xpool.ReportError(xconnection, exception); var socketException = exception.InnerException as SocketException; if (socketException != null) { this.HandleException("SocketException", invokeDesc, srequest, socketException); } this.HandleException("IOException", invokeDesc, srequest, exception); } catch (TTransportException exception) { xpool.ReportError(xconnection, exception); // 5秒以内的timeout认为是服务器积极拒绝. if (exception.Message.StartsWith("Connect timed out") && connectTookTime.TotalSeconds < 5) { // 处理异常 this.HandleException( "TTransportException", invokeDesc, srequest, new TTransportException(exception.Type, "Service unavailable.")); } else { this.HandleException("TTransportException", invokeDesc, srequest, exception); } } catch (TProtocolException exception) { xpool.ReportError(xconnection, exception); this.HandleException("TProtocolException", invokeDesc, srequest, exception); } finally { // 内部Try可以更快的释放连接。 xpool.Release(xconnection); } // 非void且result非空 if (sresponse != null && sresponse.Result != null) { // 解压 if (sresponse.Result.Compression == ThriftSCompression.Gzip) { sresponse.Result.Data = Utils.GzipUnCompress(sresponse.Result.Data); } if (sresponse.Result.ContentType == ContentTypes.Thrift) { returnValue = ThriftSerializer.Deserialize( ((MethodInfo)mcm.MethodBase).ReturnType, sresponse.Result.Data); } else { throw new NotSupportedException(string.Format("Not supported content type: {0}", sresponse.Result.ContentType)); } } returnMessage = new ReturnMessage(returnValue, null, 0, mcm.LogicalCallContext, mcm); } catch (TApplicationException tapplicationException) { var info = string.Format("tapplication exception on calling {0}. ", srequest.Uri); var exception = new ThriftSException(info + tapplicationException.Message, tapplicationException); returnMessage = new ReturnMessage(exception, mcm); } catch (BadRequestException badRequestException) { var info = string.Format("Bad request exception on calling {0}. ", srequest.Uri); var exception = new ThriftSException( info + badRequestException.ErrorMessage, info + Environment.NewLine + badRequestException.ErrorMessage); // 远端异常使用ReturnMessage包装 returnMessage = new ReturnMessage(exception, mcm); } catch (InternalServerException internalServerException) { var info = string.Format("Server internal exception on calling {0}. ", srequest.Uri); var exception = new ThriftSException( info + internalServerException.ErrorMessage, info + Environment.NewLine + internalServerException.ErrorDescription); returnMessage = new ReturnMessage(exception, mcm); } catch (InvocationException invocationException) { var info = string.Format("Server invocation exception on calling {0}. ", srequest.Uri); var exception = new ThriftSException( info + invocationException.ErrorMessage, info + Environment.NewLine + invocationException.ErrorDescription); returnMessage = new ReturnMessage(exception, mcm); } catch (Exception exception) { this.HandleException("Exception", invokeDesc, srequest, exception); } } finally { stopwatch.Stop(); } return(returnMessage); }
public Task <String> CreateSharedResource <T>(String pId, String dataTypeId, T value) where T : TBase { byte[] data = ThriftSerializer.Serialize <T>(value); return(CreateSharedResource(pId, dataTypeId, data)); }
/// <summary> /// 请求处理 /// </summary> /// <param name="request">request</param> /// <returns>response</returns> public ThriftSResponse Process(ThriftSRequest request) { if (request == null || string.IsNullOrWhiteSpace(request.ServiceName) || string.IsNullOrWhiteSpace(request.MethodName)) { throw new BadRequestException(request, "The ServiceName or MethodName must be not null."); } if (LocalCache.ServiceDictionary.ContainsKey(request.ServiceName) == false) { throw new BadRequestException(request, "Service not found."); } if (LocalCache.ServiceDictionary[request.ServiceName].ContainsKey(request.MethodName) == false) { throw new BadRequestException(request, "Method not found."); } ThriftSEnvirnment.Logger.Debug("Accept request: {0}", request.Uri); var serviceMetadata = LocalCache.ServiceDictionary[request.ServiceName][request.MethodName]; // 创建服务实例 var service = Activator.CreateInstance(serviceMetadata.ServiceHandlerType); // 参数赋值 var methodParameters = serviceMetadata.Method.GetParameters(); var invokeParameters = new Dictionary <string, object>(); for (var i = 0; i < methodParameters.Length; i++) { var parameter = methodParameters[i]; // 在跨平台的时候服务端和客户端的参数名可能完全不一样,因此唯一依据是参数顺序,请求上下文的参数名以服务端为基准。 request.Parameters[i].Name = parameter.Name; try { ThriftSEnvirnment.Logger.Debug(string.Format( new FileSizeFormatProvider(), "Request parameter:{0}, ContentType:{1}, Compress:{2}, Length:{3:fs}", parameter.Name, request.Parameters[i].ContentType, request.Parameters[i].Compression, request.Parameters[i].HasValue ? request.Parameters[i].Value.Length : 0)); // 解压 if (request.Parameters[i].Compression == ThriftSCompression.Gzip) { request.Parameters[i].Value = Utils.GzipUnCompress(request.Parameters[i].Value); } if (request.Parameters[i].HasValue == false) { invokeParameters.Add(parameter.Name, null); } else { //if (request.Parameters[i].ContentType == ContentTypes.Protobuf) //{ // invokeParameters.Add( // parameter.Name, // Utils.DeserializeFromBytes(parameter.ParameterType, request.Parameters[i].Value)); //} //else if (request.Parameters[i].ContentType == ContentTypes.Json) //{ // invokeParameters.Add( // parameter.Name, // Utils.DeserializeFromJson(parameter.ParameterType, request.Parameters[i].Value)); //}else if (request.Parameters[i].ContentType == ContentTypes.Thrift) { invokeParameters.Add( parameter.Name, ThriftSerializer.Deserialize(parameter.ParameterType, request.Parameters[i].Value)); } else { throw new NotSupportedException(string.Format("Not supported content type: {0}", request.Parameters[i].ContentType)); } } } catch (Exception ex) { throw new BadRequestException( request, string.Format("Parsing error on parameter '{0}'. {1}", parameter.Name, ex.Message)); } } var stopwatch = new Stopwatch(); object result = null; var xresponse = new ThriftSResponse() { Headers = new Dictionary <string, string>() }; xresponse.Version = Utils.Version; try { stopwatch.Start(); try { // 关联调用上下文 ThriftSContext.Current = new ThriftSContext() { Request = request }; Func <object> action = () => serviceMetadata.Handle(service, invokeParameters.Values.ToArray()); if (serviceMetadata.Attribute.IsOneWay) { action.BeginInvoke(null, null); } else { result = action(); } /* * //异步调用,可以做oneway和timeout * //Func<object> action = () => * //{ * // return serviceMetadata.Handle(service, invokeParameters.Values.ToArray()); * //}; * * //IAsyncResult asyncResult = action.BeginInvoke(null, null); * //var isGetSignal = asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(60)); * //if (isGetSignal == false) * //{ * // throw new TimeoutException("Execution timeout."); * //} * //result = action.EndInvoke(asyncResult); */ } catch (Exception ex) { throw new InvocationException() { Request = request, ErrorMessage = ex.Message, ErrorDescription = ex.ToString() }; } // 检查返回值 if (serviceMetadata.Method.ReturnType != typeof(void)) { if (result != null) { //if (Utils.GetSerializerMode(result.GetType()) == SerializerMode.ProtoBuf) //{ // xresponse.Result = new ThriftSResult() // { // ContentType = ContentTypes.Protobuf, // Compression = ThriftSCompression.None, // Data = Utils.SerializeToBytes(result) // }; //} //else if (Utils.GetSerializerMode(result.GetType()) == SerializerMode.Json) //{ // xresponse.Result = new ThriftSResult() // { // ContentType = ContentTypes.Json, // Compression = ThriftSCompression.None, // Data = Utils.SerializeToJson(result) // }; //} //else { xresponse.Result = new ThriftSResult() { ContentType = ContentTypes.Thrift, Compression = ThriftSCompression.None, Data = ThriftSerializer.Serialize(result) }; } // 大于10K开启压缩 if (xresponse.Result.Data.Length > 10 * 1024) { xresponse.Result.Data = Utils.GzipCompress(xresponse.Result.Data); xresponse.Result.Compression = ThriftSCompression.Gzip; } ThriftSEnvirnment.Logger.Debug(string.Format( new FileSizeFormatProvider(), "Render response. ContentType:{0}, Compress:{1}, Length:{2:fs}", xresponse.Result.ContentType, xresponse.Result.Compression, xresponse.Result.Data.Length)); } } } catch (Exception ex) { if (ex is InvocationException) { throw; } throw new InternalServerException() { Request = request, ErrorMessage = ex.Message, ErrorDescription = ex.ToString() }; } finally { stopwatch.Stop(); ThriftSEnvirnment.Logger.Debug("Request end. Took: {0}ms", stopwatch.Elapsed.TotalMilliseconds); } return(xresponse); }
public void TestComplexStruct() { SimpleStruct obj1 = CreateSimpleStructWithData(); ComplexStruct complex1 = new ComplexStruct(); complex1.Simple = obj1; complex1.IEnumerableProperty = new float[] { 99.99F, 88.88F }; complex1.IListProperty = complex1.IEnumerableProperty.ToList(); complex1.ISetProperty = new HashSet <float> { 55f, 66f }; complex1.IDictionaryProperty = new Dictionary <float, String> { { 1f, "A" }, { 2f, "B" } }; complex1.DictionaryIntKeyProperty = new Dictionary <int, SimpleStruct> { { 1, new SimpleStruct { StringProperty = "1Property" } }, { 2, new SimpleStruct { StringProperty = "2Property" } } }; complex1.EnumArrayProperty = new SimpleEnum[] { SimpleEnum.ValueTwo, SimpleEnum.ValueOne }; complex1.EnumDictionaryProperty = new Dictionary <string, SimpleEnum> { { "d1Enum", SimpleEnum.ValueTwo }, { "d2Enum", SimpleEnum.ValueOne } }; complex1.EnumListProperty = new List <SimpleEnum>() { SimpleEnum.ValueTwo, SimpleEnum.ValueOne }; complex1.EnumSetProperty = new HashSet <SimpleEnum> { SimpleEnum.ValueOne, SimpleEnum.ValueTwo }; complex1.IntArrayProperty = new int[] { 1, 2, 3, 4, 5 }; complex1.SimpleDictionaryProperty1 = new Dictionary <int, float> { { 1, 3.33f }, { 2, 4.44f } }; complex1.SimpleDictionaryProperty2 = new Dictionary <string, float> { { "a", 3.33f }, { "b", 4.44f } }; complex1.StructListProperty = new List <SimpleStruct> { new SimpleStruct { StringProperty = "listItem1" }, new SimpleStruct { StringProperty = "listItem2" } }; complex1.StructSetProperty = new HashSet <SimpleStruct> { new SimpleStruct { StringProperty = "setItem1" }, new SimpleStruct { StringProperty = "setItem2" } }; complex1.StructArrayProperty = new SimpleStruct[] { new SimpleStruct { StringProperty = "setItem1" }, new SimpleStruct { StringProperty = "setItem2" } }; ThriftSerializer ser = new ThriftSerializer(); byte[] objectBytes = ser.Serialize(complex1); ComplexStruct complex2 = ser.Deserialize <ComplexStruct>(objectBytes); Assert.False(Object.ReferenceEquals(complex1, complex2)); Assert.Equal(complex1.Simple, complex2.Simple); AssertEx.Equals(complex1.DictionaryIntKeyProperty, complex2.DictionaryIntKeyProperty); AssertEx.Equals(complex1.EnumArrayProperty, complex2.EnumArrayProperty); AssertEx.Equals(complex1.EnumDictionaryProperty, complex2.EnumDictionaryProperty); AssertEx.Equals(complex1.EnumListProperty, complex2.EnumListProperty); AssertEx.Equals(complex1.EnumSetProperty, complex2.EnumSetProperty); AssertEx.Equals(complex1.IntArrayProperty, complex2.IntArrayProperty); AssertEx.Equals(complex1.SimpleDictionaryProperty1, complex2.SimpleDictionaryProperty1); AssertEx.Equals(complex1.SimpleDictionaryProperty2, complex2.SimpleDictionaryProperty2); AssertEx.Equals(complex1.StructListProperty, complex2.StructListProperty); AssertEx.Equals(complex1.StructSetProperty, complex2.StructSetProperty); AssertEx.Equals(complex1.IEnumerableProperty, complex2.IEnumerableProperty); AssertEx.Equals(complex1.IListProperty, complex2.IListProperty); AssertEx.Equals(complex1.ISetProperty, complex2.ISetProperty); AssertEx.Equals(complex1.IDictionaryProperty, complex2.IDictionaryProperty); AssertEx.Equals(complex1.StructArrayProperty, complex2.StructArrayProperty); }