Skip to content

Commit

Permalink
Weakly typed actor polymorphic and null responses (dapr#1214)
Browse files Browse the repository at this point in the history
Signed-off-by: Remco Blok <[email protected]>
Co-authored-by: Remco Blok <[email protected]>
Co-authored-by: Phillip Hoff <[email protected]>
Signed-off-by: James Croft <[email protected]>
  • Loading branch information
3 people authored and jamesmcroft committed Feb 9, 2024
1 parent 2894f85 commit 5dcf216
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/Dapr.Actors/Runtime/ActorManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,13 @@ async Task<object> RequestFunc(Actor actor, CancellationToken ct)
// Serialize result if it has result (return type was not just Task.)
if (methodInfo.ReturnType.Name != typeof(Task).Name)
{
await JsonSerializer.SerializeAsync(responseBodyStream, result, result.GetType(), jsonSerializerOptions);
#if NET7_0_OR_GREATER
var resultType = methodInfo.ReturnType.GenericTypeArguments[0];
await JsonSerializer.SerializeAsync(responseBodyStream, result, resultType, jsonSerializerOptions);
#else
await JsonSerializer.SerializeAsync<object>(responseBodyStream, result, jsonSerializerOptions);
#endif

}
}

Expand Down
20 changes: 20 additions & 0 deletions test/Dapr.E2E.Test.Actors/WeaklyTypedTesting/DerivedResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed 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.
// ------------------------------------------------------------------------

namespace Dapr.E2E.Test.Actors.WeaklyTypedTesting
{
public class DerivedResponse : ResponseBase
{
public string DerivedProperty { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed 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.
// ------------------------------------------------------------------------

using System.Threading.Tasks;
using Dapr.Actors;

namespace Dapr.E2E.Test.Actors.WeaklyTypedTesting
{
public interface IWeaklyTypedTestingActor : IPingActor, IActor
{
Task<ResponseBase> GetPolymorphicResponse();

Task<ResponseBase> GetNullResponse();
}
}
25 changes: 25 additions & 0 deletions test/Dapr.E2E.Test.Actors/WeaklyTypedTesting/ResponseBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed 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.
// ------------------------------------------------------------------------

using System.Text.Json.Serialization;

namespace Dapr.E2E.Test.Actors.WeaklyTypedTesting
{
#if NET7_0_OR_GREATER
[JsonDerivedType(typeof(DerivedResponse), typeDiscriminator: nameof(DerivedResponse))]
#endif
public class ResponseBase
{
public string BasePropeprty { get; set; }
}
}
47 changes: 47 additions & 0 deletions test/Dapr.E2E.Test.App/Actors/WeaklyTypedTestingActor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed 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.
// ------------------------------------------------------------------------

using System.Threading.Tasks;
using Dapr.Actors.Runtime;

namespace Dapr.E2E.Test.Actors.WeaklyTypedTesting
{
public class WeaklyTypedTestingActor : Actor, IWeaklyTypedTestingActor
{
public WeaklyTypedTestingActor(ActorHost host)
: base(host)
{
}

public Task<ResponseBase> GetNullResponse()
{
return Task.FromResult<ResponseBase>(null);
}

public Task<ResponseBase> GetPolymorphicResponse()
{
var response = new DerivedResponse
{
BasePropeprty = "Base property value",
DerivedProperty = "Derived property value"
};

return Task.FromResult<ResponseBase>(response);
}

public Task Ping()
{
return Task.CompletedTask;
}
}
}
2 changes: 2 additions & 0 deletions test/Dapr.E2E.Test.App/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace Dapr.E2E.Test
using Dapr.E2E.Test.Actors.State;
using Dapr.E2E.Test.Actors.ExceptionTesting;
using Dapr.E2E.Test.Actors.Serialization;
using Dapr.E2E.Test.Actors.WeaklyTypedTesting;
using Dapr.E2E.Test.App.ErrorTesting;
using Dapr.Workflow;
using Microsoft.AspNetCore.Authentication;
Expand Down Expand Up @@ -106,6 +107,7 @@ public void ConfigureServices(IServiceCollection services)
options.Actors.RegisterActor<ExceptionActor>();
options.Actors.RegisterActor<SerializationActor>();
options.Actors.RegisterActor<StateActor>();
options.Actors.RegisterActor<WeaklyTypedTestingActor>();
});
}

Expand Down
68 changes: 68 additions & 0 deletions test/Dapr.E2E.Test/Actors/E2ETests.WeaklyTypedTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed 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.
// ------------------------------------------------------------------------
namespace Dapr.E2E.Test
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Dapr.Actors;
using Dapr.E2E.Test.Actors.WeaklyTypedTesting;
using FluentAssertions;
using Xunit;

public partial class E2ETests : IAsyncLifetime
{
#if NET8_0_OR_GREATER
[Fact]
public async Task WeaklyTypedActorCanReturnPolymorphicResponse()
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
var pingProxy = this.ProxyFactory.CreateActorProxy<IWeaklyTypedTestingActor>(ActorId.CreateRandom(), "WeaklyTypedTestingActor");
var proxy = this.ProxyFactory.Create(ActorId.CreateRandom(), "WeaklyTypedTestingActor");

await WaitForActorRuntimeAsync(pingProxy, cts.Token);

var result = await proxy.InvokeMethodAsync<ResponseBase>(nameof(IWeaklyTypedTestingActor.GetPolymorphicResponse));

result.Should().BeOfType<DerivedResponse>().Which.DerivedProperty.Should().NotBeNullOrWhiteSpace();
}
#else
[Fact]
public async Task WeaklyTypedActorCanReturnDerivedResponse()
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
var pingProxy = this.ProxyFactory.CreateActorProxy<IWeaklyTypedTestingActor>(ActorId.CreateRandom(), "WeaklyTypedTestingActor");
var proxy = this.ProxyFactory.Create(ActorId.CreateRandom(), "WeaklyTypedTestingActor");

await WaitForActorRuntimeAsync(pingProxy, cts.Token);

var result = await proxy.InvokeMethodAsync<DerivedResponse>(nameof(IWeaklyTypedTestingActor.GetPolymorphicResponse));

result.Should().BeOfType<DerivedResponse>().Which.DerivedProperty.Should().NotBeNullOrWhiteSpace();
}
#endif
[Fact]
public async Task WeaklyTypedActorCanReturnNullResponse()
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60));
var pingProxy = this.ProxyFactory.CreateActorProxy<IWeaklyTypedTestingActor>(ActorId.CreateRandom(), "WeaklyTypedTestingActor");
var proxy = this.ProxyFactory.Create(ActorId.CreateRandom(), "WeaklyTypedTestingActor");

await WaitForActorRuntimeAsync(pingProxy, cts.Token);

var result = await proxy.InvokeMethodAsync<ResponseBase>(nameof(IWeaklyTypedTestingActor.GetNullResponse));

result.Should().BeNull();
}
}
}

0 comments on commit 5dcf216

Please sign in to comment.