/// <summary>
        /// Gets the exception from the ActorInvokeException.
        /// </summary>
        /// <param name="stream">The stream that contains the serialized exception or exception message.</param>
        /// <param name="result">Exception from the remote side.</param>
        /// <returns>true if there was a valid exception, false otherwise.</returns>
        internal static bool ToException(Stream stream, out Exception result)
        {
            // try to de-serialize the bytes in to exception requestMessage and create service exception
            if (ActorInvokeException.TryDeserialize(stream, out result))
            {
                return(true);
            }

            return(false);
        }
        internal static bool TryDeserialize(Stream stream, out Exception result, ILogger logger = null)
        {
            try
            {
                stream.Seek(0, SeekOrigin.Begin);
                var eData = ActorInvokeExceptionData.Deserialize(stream);
                result = new ActorInvokeException(eData.Type, eData.Message);
                return(true);
            }
            catch (Exception e)
            {
                // swallowing the exception
                logger?.LogWarning("RemoteException", "DeSerialization failed : Reason  {0}", e);
            }

            result = null;
            return(false);
        }
Exemple #3
0
        public async Task <IActorResponseMessage> InvokeActorMethodWithRemotingAsync(ActorMessageSerializersManager serializersManager, IActorRequestMessage remotingRequestRequestMessage, CancellationToken cancellationToken = default)
        {
            var requestMessageHeader = remotingRequestRequestMessage.GetHeader();

            var actorId     = requestMessageHeader.ActorId.ToString();
            var methodName  = requestMessageHeader.MethodName;
            var actorType   = requestMessageHeader.ActorType;
            var interfaceId = requestMessageHeader.InterfaceId;

            var serializedHeader = serializersManager.GetHeaderSerializer()
                                   .SerializeRequestHeader(remotingRequestRequestMessage.GetHeader());

            var msgBodySeriaizer  = serializersManager.GetRequestMessageBodySerializer(interfaceId);
            var serializedMsgBody = msgBodySeriaizer.Serialize(remotingRequestRequestMessage.GetBody());

            // Send Request
            var relativeUrl = string.Format(CultureInfo.InvariantCulture, Constants.ActorMethodRelativeUrlFormat, actorType, actorId, methodName);

            HttpRequestMessage RequestFunc()
            {
                var request = new HttpRequestMessage()
                {
                    Method = HttpMethod.Put,
                };

                if (serializedMsgBody != null)
                {
                    request.Content = new ByteArrayContent(serializedMsgBody);
                    request.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/octet-stream; charset=utf-8");
                }

                request.Headers.Add(Constants.RequestHeaderName, Encoding.UTF8.GetString(serializedHeader, 0, serializedHeader.Length));

                return(request);
            }

            var retval = await this.SendAsync(RequestFunc, relativeUrl, cancellationToken);

            IActorResponseMessageHeader actorResponseMessageHeader = null;

            if (retval != null && retval.Headers != null)
            {
                if (retval.Headers.TryGetValues(Constants.ErrorResponseHeaderName, out IEnumerable <string> headerValues))
                {
                    var header = headerValues.First();

                    // DeSerialize Actor Response Message Header
                    actorResponseMessageHeader =
                        serializersManager.GetHeaderSerializer()
                        .DeserializeResponseHeaders(
                            new MemoryStream(Encoding.ASCII.GetBytes(header)));
                }
            }

            // Get the http response message body content and extract out expected actor response message body
            IActorResponseMessageBody actorResponseMessageBody = null;

            if (retval != null && retval.Content != null)
            {
                var responseMessageBody = await retval.Content.ReadAsStreamAsync();

                // Deserialize Actor Response Message Body
                // Deserialize to ActorInvokeException when there is response header otherwise normal path
                var responseBodySerializer = serializersManager.GetResponseMessageBodySerializer(interfaceId);

                // actorResponseMessageHeader is not null, it means there is remote exception
                if (actorResponseMessageHeader != null)
                {
                    var isDeserialzied =
                        ActorInvokeException.ToException(
                            responseMessageBody,
                            out var remoteMethodException);
                    if (isDeserialzied)
                    {
                        throw new ActorMethodInvocationException(
                                  "Remote Actor Method Exception",
                                  remoteMethodException,
                                  false /* non transient */);
                    }
                    else
                    {
                        throw new ActorInvokeException(remoteMethodException.GetType().FullName, string.Format(
                                                           CultureInfo.InvariantCulture,
                                                           SR.ErrorDeserializationFailure,
                                                           remoteMethodException.ToString()));
                    }
                }

                actorResponseMessageBody = responseBodySerializer.Deserialize(responseMessageBody);
            }

            return(new ActorResponseMessage(actorResponseMessageHeader, actorResponseMessageBody));
        }