public ActorResponseMessage(
     IActorResponseMessageHeader header,
     IActorResponseMessageBody msgBody)
 {
     this.header  = header;
     this.msgBody = msgBody;
 }
        internal async Task <Tuple <string, byte[]> > DispatchWithRemotingAsync(ActorId actorId, string actorMethodName, string daprActorheader, Stream data, CancellationToken cancellationToken)
        {
            var actorMethodContext = ActorMethodContext.CreateForActor(actorMethodName);

            // Get the serialized header
            var actorMessageHeader = this.serializersManager.GetHeaderSerializer()
                                     .DeserializeRequestHeaders(new MemoryStream(Encoding.ASCII.GetBytes(daprActorheader)));

            var interfaceId = actorMessageHeader.InterfaceId;

            // Get the deserialized Body.
            var msgBodySerializer = this.serializersManager.GetRequestMessageBodySerializer(actorMessageHeader.InterfaceId);

            IActorRequestMessageBody actorMessageBody;

            using (var stream = new MemoryStream())
            {
                await data.CopyToAsync(stream);

                actorMessageBody = msgBodySerializer.Deserialize(stream);
            }

            // Call the method on the method dispatcher using the Func below.
            var methodDispatcher = this.methodDispatcherMap.GetDispatcher(actorMessageHeader.InterfaceId, actorMessageHeader.MethodId);

            // Create a Func to be invoked by common method.
            async Task <Tuple <string, byte[]> > RequestFunc(Actor actor, CancellationToken ct)
            {
                IActorResponseMessageBody responseMsgBody = null;

                try
                {
                    responseMsgBody = (IActorResponseMessageBody)await methodDispatcher.DispatchAsync(
                        actor,
                        actorMessageHeader.MethodId,
                        actorMessageBody,
                        this.messageBodyFactory,
                        ct);

                    return(this.CreateResponseMessage(responseMsgBody, interfaceId));
                }
                catch (Exception exception)
                {
                    // return exception response message
                    return(this.CreateExceptionResponseMessage(exception));
                }
            }

            return(await this.DispatchInternalAsync(actorId, actorMethodContext, RequestFunc, cancellationToken));
        }
Beispiel #3
0
            byte[] IActorResponseMessageBodySerializer.Serialize(IActorResponseMessageBody actorResponseMessageBody)
            {
                if (actorResponseMessageBody == null)
                {
                    return(null);
                }

                using var stream = new MemoryStream();
                using var writer = this.CreateXmlDictionaryWriter(stream);
                this.serializer.WriteObject(writer, actorResponseMessageBody);
                writer.Flush();

                return(stream.ToArray());
            }
Beispiel #4
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);
            var requestId   = Guid.NewGuid().ToString();

            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, requestId, 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 RemoteException 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 =
                        RemoteException.ToException(
                            responseMessageBody,
                            out var remoteMethodException);
                    if (isDeserialzied)
                    {
                        throw new ActorMethodInvocationException(
                                  "Remote Actor Method Exception",
                                  remoteMethodException,
                                  false /* non transient */);
                    }
                    else
                    {
                        throw new ServiceException(remoteMethodException.GetType().FullName, string.Format(
                                                       CultureInfo.InvariantCulture,
                                                       SR.ErrorDeserializationFailure,
                                                       remoteMethodException.ToString()));
                    }
                }

                actorResponseMessageBody = responseBodySerializer.Deserialize(responseMessageBody);
            }

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