Skip to content

Commit 4dc9fc3

Browse files
committed
Now the json serialization should work with multiple methods in an interface
Signed-off-by: paule96 <[email protected]>
1 parent 5412da5 commit 4dc9fc3

File tree

4 files changed

+42
-19
lines changed

4 files changed

+42
-19
lines changed

src/Dapr.Actors/Communication/ActorMessageBodyJsonSerializationProvider.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,10 @@ public MemoryStreamMessageBodySerializer(
104104
{
105105
var _methodRequestParameterTypes = new List<Type>(methodRequestParameterTypes);
106106
var _wrappedRequestMessageTypes = new List<Type>(wrappedRequestMessageTypes);
107-
107+
if(_wrappedRequestMessageTypes.Count != 1){
108+
throw new NotSupportedException("JSON serialisation should always provide the actor method, that was called" +
109+
" to support (de)serialisation. This is a dapr sdk error, open an issue on github.");
110+
}
108111
this.serializerOptions = new(serializerOptions)
109112
{
110113
// Workaround since WrappedMessageBody creates an object

src/Dapr.Actors/Communication/ActorMessageSerializersManager.cs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@ namespace Dapr.Actors.Communication
1515
{
1616
using System;
1717
using System.Collections.Concurrent;
18+
using System.Collections.Generic;
19+
using System.Diagnostics.CodeAnalysis;
20+
using System.Linq;
1821
using Dapr.Actors.Builder;
1922

2023
internal class ActorMessageSerializersManager
2124
{
22-
private readonly ConcurrentDictionary<int, CacheEntry> cachedBodySerializers;
25+
private readonly ConcurrentDictionary<(int, string), CacheEntry> cachedBodySerializers;
2326
private readonly IActorMessageHeaderSerializer headerSerializer;
2427
private readonly IActorMessageBodySerializationProvider serializationProvider;
2528

@@ -38,7 +41,7 @@ public ActorMessageSerializersManager(
3841
}
3942

4043
this.serializationProvider = serializationProvider;
41-
this.cachedBodySerializers = new ConcurrentDictionary<int, CacheEntry>();
44+
this.cachedBodySerializers = new ConcurrentDictionary<(int, string), CacheEntry>();
4245
this.headerSerializer = headerSerializer;
4346
}
4447

@@ -52,19 +55,19 @@ public IActorMessageHeaderSerializer GetHeaderSerializer()
5255
return this.headerSerializer;
5356
}
5457

55-
public IActorRequestMessageBodySerializer GetRequestMessageBodySerializer(int interfaceId)
58+
public IActorRequestMessageBodySerializer GetRequestMessageBodySerializer(int interfaceId, [AllowNull] string methodName = null)
5659
{
57-
return this.cachedBodySerializers.GetOrAdd(interfaceId, this.CreateSerializers).RequestMessageBodySerializer;
60+
return this.cachedBodySerializers.GetOrAdd((interfaceId, methodName), this.CreateSerializers).RequestMessageBodySerializer;
5861
}
5962

60-
public IActorResponseMessageBodySerializer GetResponseMessageBodySerializer(int interfaceId)
63+
public IActorResponseMessageBodySerializer GetResponseMessageBodySerializer(int interfaceId, [AllowNull] string methodName = null)
6164
{
62-
return this.cachedBodySerializers.GetOrAdd(interfaceId, this.CreateSerializers).ResponseMessageBodySerializer;
65+
return this.cachedBodySerializers.GetOrAdd((interfaceId, methodName), this.CreateSerializers).ResponseMessageBodySerializer;
6366
}
6467

65-
internal CacheEntry CreateSerializers(int interfaceId)
68+
internal CacheEntry CreateSerializers((int interfaceId, string methodName) data)
6669
{
67-
var interfaceDetails = this.GetInterfaceDetails(interfaceId);
70+
var interfaceDetails = this.GetInterfaceDetails(data.interfaceId);
6871

6972
// get the service interface type from the code gen layer
7073
var serviceInterfaceType = interfaceDetails.ServiceInterfaceType;
@@ -74,10 +77,27 @@ internal CacheEntry CreateSerializers(int interfaceId)
7477

7578
// get the known types from the codegen layer
7679
var responseBodyTypes = interfaceDetails.ResponseKnownTypes;
80+
if (data.methodName is null)
81+
{
82+
// Path is mainly used for XML serialization
83+
return new CacheEntry(
84+
this.serializationProvider.CreateRequestMessageBodySerializer(serviceInterfaceType, requestBodyTypes, interfaceDetails.RequestWrappedKnownTypes),
85+
this.serializationProvider.CreateResponseMessageBodySerializer(serviceInterfaceType, responseBodyTypes, interfaceDetails.ResponseWrappedKnownTypes));
86+
}
87+
else
88+
{
89+
// This path should be used for JSON serialization
90+
var requestWrapperTypeAsList = new List<Type>(1){
91+
interfaceDetails.RequestWrappedKnownTypes.Single(r => r.Name == $"{data.methodName}ReqBody")
92+
};
93+
var responseWrapperTypeAsList = new List<Type>(1){
94+
interfaceDetails.RequestWrappedKnownTypes.Single(r => r.Name == $"{data.methodName}RespBody")
95+
};
96+
return new CacheEntry(
97+
this.serializationProvider.CreateRequestMessageBodySerializer(serviceInterfaceType, requestBodyTypes, requestWrapperTypeAsList),
98+
this.serializationProvider.CreateResponseMessageBodySerializer(serviceInterfaceType, responseBodyTypes, responseWrapperTypeAsList));
99+
}
77100

78-
return new CacheEntry(
79-
this.serializationProvider.CreateRequestMessageBodySerializer(serviceInterfaceType, requestBodyTypes, interfaceDetails.RequestWrappedKnownTypes),
80-
this.serializationProvider.CreateResponseMessageBodySerializer(serviceInterfaceType, responseBodyTypes, interfaceDetails.ResponseWrappedKnownTypes));
81101
}
82102

83103
internal InterfaceDetails GetInterfaceDetails(int interfaceId)

src/Dapr.Actors/DaprHttpInteractor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public async Task<IActorResponseMessage> InvokeActorMethodWithRemotingAsync(Acto
116116
var serializedHeader = serializersManager.GetHeaderSerializer()
117117
.SerializeRequestHeader(remotingRequestRequestMessage.GetHeader());
118118

119-
var msgBodySeriaizer = serializersManager.GetRequestMessageBodySerializer(interfaceId);
119+
var msgBodySeriaizer = serializersManager.GetRequestMessageBodySerializer(interfaceId, methodName);
120120
var serializedMsgBody = msgBodySeriaizer.Serialize(remotingRequestRequestMessage.GetBody());
121121

122122
// Send Request
@@ -170,7 +170,7 @@ HttpRequestMessage RequestFunc()
170170

171171
// Deserialize Actor Response Message Body
172172
// Deserialize to ActorInvokeException when there is response header otherwise normal path
173-
var responseBodySerializer = serializersManager.GetResponseMessageBodySerializer(interfaceId);
173+
var responseBodySerializer = serializersManager.GetResponseMessageBodySerializer(interfaceId, methodName);
174174

175175
// actorResponseMessageHeader is not null, it means there is remote exception
176176
if (actorResponseMessageHeader != null)

src/Dapr.Actors/Runtime/ActorManager.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ internal async Task<Tuple<string, byte[]>> DispatchWithRemotingAsync(ActorId act
106106
var interfaceId = actorMessageHeader.InterfaceId;
107107

108108
// Get the deserialized Body.
109-
var msgBodySerializer = this.serializersManager.GetRequestMessageBodySerializer(actorMessageHeader.InterfaceId);
110-
109+
var msgBodySerializer = this.serializersManager.GetRequestMessageBodySerializer(actorMessageHeader.InterfaceId, actorMethodContext.MethodName);
110+
111111
IActorRequestMessageBody actorMessageBody;
112112
using (var stream = new MemoryStream())
113113
{
@@ -130,7 +130,7 @@ async Task<Tuple<string, byte[]>> RequestFunc(Actor actor, CancellationToken ct)
130130
this.messageBodyFactory,
131131
ct);
132132

133-
return this.CreateResponseMessage(responseMsgBody, interfaceId);
133+
return this.CreateResponseMessage(responseMsgBody, interfaceId, actorMethodContext.MethodName);
134134
}
135135

136136
return await this.DispatchInternalAsync(actorId, actorMethodContext, RequestFunc, cancellationToken);
@@ -387,12 +387,12 @@ private async Task<T> DispatchInternalAsync<T>(ActorId actorId, ActorMethodConte
387387
return retval;
388388
}
389389

390-
private Tuple<string, byte[]> CreateResponseMessage(IActorResponseMessageBody msgBody, int interfaceId)
390+
private Tuple<string, byte[]> CreateResponseMessage(IActorResponseMessageBody msgBody, int interfaceId, string methodName)
391391
{
392392
var responseMsgBodyBytes = Array.Empty<byte>();
393393
if (msgBody != null)
394394
{
395-
var responseSerializer = this.serializersManager.GetResponseMessageBodySerializer(interfaceId);
395+
var responseSerializer = this.serializersManager.GetResponseMessageBodySerializer(interfaceId, methodName);
396396
responseMsgBodyBytes = responseSerializer.Serialize(msgBody);
397397
}
398398

0 commit comments

Comments
 (0)