Adds support for providing pubsub and topic names during runtime.

- Fixes #680
This commit is contained in:
Martin Björkström 2021-05-16 21:42:41 +03:00 committed by Ryan Nowak
parent 2ddb4bb7e0
commit 638bf4c6dc
7 changed files with 63 additions and 24 deletions

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Builder
public static class DaprEndpointConventionBuilderExtensions
{
/// <summary>
/// Adds <see cref="TopicAttribute" /> metadata to the provided <see cref="IEndpointConventionBuilder" />.
/// Adds <see cref="ITopicMetadata" /> metadata to the provided <see cref="IEndpointConventionBuilder" />.
/// </summary>
/// <param name="builder">The <see cref="IEndpointConventionBuilder" />.</param>\
/// <param name="pubsubName">The name of the pubsub component to use.</param>

View File

@ -39,9 +39,9 @@ namespace Microsoft.AspNetCore.Builder
var dataSource = context.RequestServices.GetRequiredService<EndpointDataSource>();
var entries = dataSource.Endpoints
.OfType<RouteEndpoint>()
.Where(e => e.Metadata.GetMetadata<TopicAttribute>()?.Name != null) // only endpoints which have TopicAttribute with not null Name.
.Where(e => e.Metadata.GetMetadata<ITopicMetadata>()?.Name != null) // only endpoints which have TopicAttribute with not null Name.
.Distinct()
.Select(e => (e.Metadata.GetMetadata<TopicAttribute>().PubsubName, e.Metadata.GetMetadata<TopicAttribute>().Name, e.RoutePattern));
.Select(e => (e.Metadata.GetMetadata<ITopicMetadata>().PubsubName, e.Metadata.GetMetadata<ITopicMetadata>().Name, e.RoutePattern));
context.Response.ContentType = "application/json";
using var writer = new Utf8JsonWriter(context.Response.BodyWriter);

View File

@ -0,0 +1,18 @@
namespace Dapr
{
/// <summary>
/// Metadata that describes an endpoint as a subscriber to a topic.
/// </summary>
public interface ITopicMetadata
{
/// <summary>
/// Gets the topic name.
/// </summary>
string Name { get; }
/// <summary>
/// Gets the pubsub component name name.
/// </summary>
string PubsubName { get; }
}
}

View File

@ -10,7 +10,7 @@ namespace Dapr
/// <summary>
/// Metadata that describes an endpoint as a subscriber to a topic.
/// </summary>
public class TopicAttribute : Attribute
public class TopicAttribute : Attribute, ITopicMetadata
{
/// <summary>
/// Initializes a new instance of the <see cref="TopicAttribute" /> class.
@ -26,14 +26,10 @@ namespace Dapr
this.PubsubName = pubsubName;
}
/// <summary>
/// Gets the topic name.
/// </summary>
/// <inheritdoc/>
public string Name { get; }
/// <summary>
/// Gets the pubsub component name name.
/// </summary>
/// <inheritdoc/>
public string PubsubName { get; }
}
}

View File

@ -0,0 +1,22 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
namespace Dapr.AspNetCore.IntegrationTest.App
{
using System;
public class CustomTopicAttribute : Attribute, ITopicMetadata
{
public CustomTopicAttribute(string pubsubName, string name)
{
this.Name = "custom-" + name;
this.PubsubName = "custom-" + pubsubName;
}
public string Name { get; }
public string PubsubName { get; }
}
}

View File

@ -22,6 +22,12 @@ namespace Dapr.AspNetCore.IntegrationTest.App
{
}
[CustomTopic("pubsub", "C")]
[HttpPost("/C")]
public void TopicC()
{
}
[Topic("pubsub", "register-user")]
[HttpPost("/register-user")]
public ActionResult<UserInfo> RegisterUser(UserInfo user)

View File

@ -30,24 +30,21 @@ namespace Dapr.AspNetCore.IntegrationTest
var json = await JsonSerializer.DeserializeAsync<JsonElement>(stream);
json.ValueKind.Should().Be(JsonValueKind.Array);
json.GetArrayLength().Should().Be(4);
var topics = new List<string>();
var routes = new List<string>();
json.GetArrayLength().Should().Be(5);
var metadata = new List<(string PubsubName, string Topic, string Route)>();
foreach (var element in json.EnumerateArray())
{
topics.Add(element.GetProperty("topic").GetString());
routes.Add(element.GetProperty("route").GetString());
var pubsubName = element.GetProperty("pubsubName").GetString();
var topic = element.GetProperty("topic").GetString();
var route = element.GetProperty("route").GetString();
metadata.Add((pubsubName, topic, route));
}
topics.Should().Contain("A");
topics.Should().Contain("B");
topics.Should().Contain("register-user");
topics.Should().Contain("register-user-plaintext");
routes.Should().Contain("B");
routes.Should().Contain("topic-a");
routes.Should().Contain("register-user");
routes.Should().Contain("register-user-plaintext");
metadata.Should().Contain(("testpubsub", "A", "topic-a"));
metadata.Should().Contain(("pubsub", "B", "B"));
metadata.Should().Contain(("custom-pubsub", "custom-C", "C"));
metadata.Should().Contain(("pubsub", "register-user", "register-user"));
metadata.Should().Contain(("pubsub", "register-user-plaintext", "register-user-plaintext"));
}
}
}