diff --git a/examples/AspNetCore/ControllerSample/Controllers/SampleController.cs b/examples/AspNetCore/ControllerSample/Controllers/SampleController.cs
index 9d821999..a8071778 100644
--- a/examples/AspNetCore/ControllerSample/Controllers/SampleController.cs
+++ b/examples/AspNetCore/ControllerSample/Controllers/SampleController.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
// 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.
@@ -155,5 +155,18 @@ namespace ControllerSample.Controllers
{
return Ok();
}
+
+ ///
+ /// Method which uses for binding this endpoint to a subscription and adds routingkey metadata.
+ ///
+ ///
+ ///
+ [Topic("pubsub", "topicmetadata")]
+ [TopicMetadata("routingKey", "keyA")]
+ [HttpPost("examplecustomtopicmetadata")]
+ public ActionResult ExampleCustomTopicMetadata(Transaction transaction)
+ {
+ return Ok();
+ }
}
}
diff --git a/src/Dapr.AspNetCore/DaprEndpointConventionBuilderExtensions.cs b/src/Dapr.AspNetCore/DaprEndpointConventionBuilderExtensions.cs
index 40b7e966..b29b8150 100644
--- a/src/Dapr.AspNetCore/DaprEndpointConventionBuilderExtensions.cs
+++ b/src/Dapr.AspNetCore/DaprEndpointConventionBuilderExtensions.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
// 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.
@@ -14,6 +14,7 @@
namespace Microsoft.AspNetCore.Builder
{
using System;
+ using System.Collections.Generic;
using Dapr;
///
@@ -35,6 +36,24 @@ namespace Microsoft.AspNetCore.Builder
return WithTopic(builder, pubsubName, name, false);
}
+ ///
+ /// Adds metadata to the provided .
+ ///
+ /// The .\
+ /// The name of the pubsub component to use.
+ /// The topic name.
+ ///
+ /// A collection of metadata key-value pairs that will be provided to the pubsub. The valid metadata keys and values
+ /// are determined by the type of pubsub component used.
+ ///
+ /// The type.
+ /// The builder object.
+ public static T WithTopic(this T builder, string pubsubName, string name, IDictionary metadata)
+ where T : IEndpointConventionBuilder
+ {
+ return WithTopic(builder, pubsubName, name, false, metadata);
+ }
+
///
/// Adds metadata to the provided .
///
@@ -46,6 +65,25 @@ namespace Microsoft.AspNetCore.Builder
/// The builder object.
public static T WithTopic(this T builder, string pubsubName, string name, bool enableRawPayload)
where T : IEndpointConventionBuilder
+ {
+ return WithTopic(builder, pubsubName, name, enableRawPayload, null);
+ }
+
+ ///
+ /// Adds metadata to the provided .
+ ///
+ /// The .\
+ /// The name of the pubsub component to use.
+ /// The topic name.
+ /// The enable/disable raw pay load flag.
+ ///
+ /// A collection of metadata key-value pairs that will be provided to the pubsub. The valid metadata keys and values
+ /// are determined by the type of pubsub component used.
+ ///
+ /// The type.
+ /// The builder object.
+ public static T WithTopic(this T builder, string pubsubName, string name, bool enableRawPayload, IDictionary metadata)
+ where T : IEndpointConventionBuilder
{
if (builder is null)
{
@@ -56,6 +94,13 @@ namespace Microsoft.AspNetCore.Builder
ArgumentVerifier.ThrowIfNullOrEmpty(name, nameof(name));
builder.WithMetadata(new TopicAttribute(pubsubName, name, enableRawPayload));
+ if (metadata is not null)
+ {
+ foreach (var md in metadata)
+ {
+ builder.WithMetadata(new TopicMetadataAttribute(md.Key, md.Value));
+ }
+ }
return builder;
}
}
diff --git a/src/Dapr.AspNetCore/DaprEndpointRouteBuilderExtensions.cs b/src/Dapr.AspNetCore/DaprEndpointRouteBuilderExtensions.cs
index 6eda1d9c..6269fb7d 100644
--- a/src/Dapr.AspNetCore/DaprEndpointRouteBuilderExtensions.cs
+++ b/src/Dapr.AspNetCore/DaprEndpointRouteBuilderExtensions.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
// 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.
@@ -70,7 +70,9 @@ namespace Microsoft.AspNetCore.Builder
.SelectMany(e =>
{
var topicMetadata = e.Metadata.GetOrderedMetadata();
- var subs = new List<(string PubsubName, string Name, bool? EnableRawPayload, string Match, int Priority, RoutePattern RoutePattern)>();
+ var originalTopicMetadata = e.Metadata.GetOrderedMetadata();
+
+ var subs = new List<(string PubsubName, string Name, bool? EnableRawPayload, string Match, int Priority, Dictionary OriginalTopicMetadata, string MetadataSeparator, RoutePattern RoutePattern)>();
for (int i = 0; i < topicMetadata.Count(); i++)
{
@@ -79,6 +81,10 @@ namespace Microsoft.AspNetCore.Builder
(topicMetadata[i] as IRawTopicMetadata)?.EnableRawPayload,
topicMetadata[i].Match,
topicMetadata[i].Priority,
+ originalTopicMetadata.Where(m => (topicMetadata[i] as IOwnedOriginalTopicMetadata)?.OwnedMetadatas?.Any(o => o.Equals(m.Id)) == true || string.IsNullOrEmpty(m.Id))
+ .GroupBy(c => c.Name)
+ .ToDictionary(m => m.Key, m => m.Select(c => c.Value).Distinct().ToArray()),
+ (topicMetadata[i] as IOwnedOriginalTopicMetadata)?.MetadataSeparator,
e.RoutePattern));
}
@@ -91,10 +97,18 @@ namespace Microsoft.AspNetCore.Builder
{
var first = e.First();
var rawPayload = e.Any(e => e.EnableRawPayload.GetValueOrDefault());
+ var metadataSeparator = e.FirstOrDefault(e => string.IsNullOrEmpty(e.MetadataSeparator)).MetadataSeparator ?? ",";
var rules = e.Where(e => !string.IsNullOrEmpty(e.Match)).ToList();
var defaultRoutes = e.Where(e => string.IsNullOrEmpty(e.Match)).Select(e => RoutePatternToString(e.RoutePattern)).ToList();
var defaultRoute = defaultRoutes.FirstOrDefault();
+ //multiple identical names. use comma separation.
+ var metadata = new Metadata(e.SelectMany(c => c.OriginalTopicMetadata).GroupBy(c => c.Key).ToDictionary(c => c.Key, c => string.Join(metadataSeparator, c.SelectMany(c => c.Value).Distinct())));
+ if (rawPayload || options?.EnableRawPayload is true)
+ {
+ metadata.Add(Metadata.RawPayload, "true");
+ }
+
if (logger != null)
{
if (defaultRoutes.Count > 1)
@@ -116,10 +130,7 @@ namespace Microsoft.AspNetCore.Builder
{
Topic = first.Name,
PubsubName = first.PubsubName,
- Metadata = rawPayload ? new Metadata
- {
- RawPayload = "true",
- } : null,
+ Metadata = metadata.Count > 0 ? metadata : null,
};
// Use the V2 routing rules structure
@@ -154,7 +165,8 @@ namespace Microsoft.AspNetCore.Builder
});
}
- private static string RoutePatternToString(RoutePattern routePattern) {
+ private static string RoutePatternToString(RoutePattern routePattern)
+ {
return string.Join("/", routePattern.PathSegments
.Select(segment => string.Concat(segment.Parts.Cast()
.Select(part => part.Content))));
diff --git a/src/Dapr.AspNetCore/IOriginalTopicMetadata.cs b/src/Dapr.AspNetCore/IOriginalTopicMetadata.cs
new file mode 100644
index 00000000..71aa952c
--- /dev/null
+++ b/src/Dapr.AspNetCore/IOriginalTopicMetadata.cs
@@ -0,0 +1,40 @@
+// ------------------------------------------------------------------------
+// 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
+{
+ ///
+ /// IOriginalTopicMetadata that describes subscribe endpoint to a topic original metadata.
+ ///
+ public interface IOriginalTopicMetadata
+ {
+ ///
+ /// Gets the topic metadata id.
+ ///
+ ///
+ /// It is only used for simple identification,. When it is empty, it can be used for all topics in the current context.
+ ///
+ string Id { get; }
+
+ ///
+ /// Gets the topic metadata name.
+ ///
+ /// Multiple identical names. only the first is valid.
+ string Name { get; }
+
+ ///
+ /// Gets the topic metadata value.
+ ///
+ string Value { get; }
+ }
+}
diff --git a/src/Dapr.AspNetCore/IOwnedOriginalTopicMetadata.cs b/src/Dapr.AspNetCore/IOwnedOriginalTopicMetadata.cs
new file mode 100644
index 00000000..36ae45e5
--- /dev/null
+++ b/src/Dapr.AspNetCore/IOwnedOriginalTopicMetadata.cs
@@ -0,0 +1,33 @@
+// ------------------------------------------------------------------------
+// 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
+{
+ ///
+ /// IOwnedOriginalTopicMetadata that describes subscribe endpoint to topic owned metadata.
+ ///
+ public interface IOwnedOriginalTopicMetadata
+ {
+ ///
+ /// Gets the owned by topic.
+ ///
+ /// When the is not empty, the metadata owned by topic.
+ string[] OwnedMetadatas { get; }
+
+ ///
+ /// Get separator to use for metadata
+ ///
+ /// Separator to be used for when multiple values exist for a .
+ string MetadataSeparator { get; }
+ }
+}
diff --git a/src/Dapr.AspNetCore/Subscription.cs b/src/Dapr.AspNetCore/Subscription.cs
index 828e2c8b..54e41956 100644
--- a/src/Dapr.AspNetCore/Subscription.cs
+++ b/src/Dapr.AspNetCore/Subscription.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
// 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.
@@ -49,12 +49,16 @@ namespace Dapr
///
/// This class defines the metadata for subscribe endpoint.
///
- internal class Metadata
+ internal class Metadata : Dictionary
{
+ public Metadata() { }
+
+ public Metadata(IDictionary dictionary) : base(dictionary) { }
+
///
- /// Gets or sets the raw payload
+ /// RawPayload key
///
- public string RawPayload { get; set; }
+ internal const string RawPayload = "rawPayload";
}
internal class Routes
diff --git a/src/Dapr.AspNetCore/TopicAttribute.cs b/src/Dapr.AspNetCore/TopicAttribute.cs
index 08c3bac9..24d47f62 100644
--- a/src/Dapr.AspNetCore/TopicAttribute.cs
+++ b/src/Dapr.AspNetCore/TopicAttribute.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
// 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.
@@ -19,20 +19,24 @@ namespace Dapr
/// TopicAttribute describes an endpoint as a subscriber to a topic.
///
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
- public class TopicAttribute : Attribute, ITopicMetadata, IRawTopicMetadata
+ public class TopicAttribute : Attribute, ITopicMetadata, IRawTopicMetadata, IOwnedOriginalTopicMetadata
{
///
/// Initializes a new instance of the class.
///
/// The name of the pubsub component to use.
/// The topic name.
- public TopicAttribute(string pubsubName, string name)
+ /// The topic owned metadata ids.
+ /// Separator to use for metadata.
+ public TopicAttribute(string pubsubName, string name, string[] ownedMetadatas = null,string metadataSeparator = ",")
{
ArgumentVerifier.ThrowIfNullOrEmpty(pubsubName, nameof(pubsubName));
ArgumentVerifier.ThrowIfNullOrEmpty(name, nameof(name));
this.Name = name;
this.PubsubName = pubsubName;
+ this.OwnedMetadatas = ownedMetadatas;
+ this.MetadataSeparator = metadataSeparator;
}
///
@@ -41,7 +45,9 @@ namespace Dapr
/// The name of the pubsub component to use.
/// The topic name.
/// The enable/disable raw pay load flag.
- public TopicAttribute(string pubsubName, string name, bool enableRawPayload)
+ /// The topic owned metadata ids.
+ /// Separator to use for metadata.
+ public TopicAttribute(string pubsubName, string name, bool enableRawPayload, string[] ownedMetadatas = null, string metadataSeparator = ",")
{
ArgumentVerifier.ThrowIfNullOrEmpty(pubsubName, nameof(pubsubName));
ArgumentVerifier.ThrowIfNullOrEmpty(name, nameof(name));
@@ -49,6 +55,8 @@ namespace Dapr
this.Name = name;
this.PubsubName = pubsubName;
this.EnableRawPayload = enableRawPayload;
+ this.OwnedMetadatas = ownedMetadatas;
+ this.MetadataSeparator = metadataSeparator;
}
///
@@ -58,7 +66,9 @@ namespace Dapr
/// The topic name.
/// The CEL expression to test the cloud event with.
/// The priority of the rule (low-to-high values).
- public TopicAttribute(string pubsubName, string name, string match, int priority)
+ /// The topic owned metadata ids.
+ /// Separator to use for metadata.
+ public TopicAttribute(string pubsubName, string name, string match, int priority, string[] ownedMetadatas = null, string metadataSeparator = ",")
{
ArgumentVerifier.ThrowIfNullOrEmpty(pubsubName, nameof(pubsubName));
ArgumentVerifier.ThrowIfNullOrEmpty(name, nameof(name));
@@ -67,6 +77,8 @@ namespace Dapr
this.PubsubName = pubsubName;
this.Match = match;
this.Priority = priority;
+ this.OwnedMetadatas = ownedMetadatas;
+ this.MetadataSeparator = metadataSeparator;
}
///
@@ -77,7 +89,9 @@ namespace Dapr
/// The enable/disable raw pay load flag.
/// The CEL expression to test the cloud event with.
/// The priority of the rule (low-to-high values).
- public TopicAttribute(string pubsubName, string name, bool enableRawPayload, string match, int priority)
+ /// The topic owned metadata ids.
+ /// Separator to use for metadata.
+ public TopicAttribute(string pubsubName, string name, bool enableRawPayload, string match, int priority, string[] ownedMetadatas = null, string metadataSeparator = ",")
{
ArgumentVerifier.ThrowIfNullOrEmpty(pubsubName, nameof(pubsubName));
ArgumentVerifier.ThrowIfNullOrEmpty(name, nameof(name));
@@ -87,6 +101,8 @@ namespace Dapr
this.EnableRawPayload = enableRawPayload;
this.Match = match;
this.Priority = priority;
+ this.OwnedMetadatas = ownedMetadatas;
+ this.MetadataSeparator = metadataSeparator;
}
///
@@ -103,5 +119,11 @@ namespace Dapr
///
public int Priority { get; }
+
+ ///
+ public string[] OwnedMetadatas { get; }
+
+ ///
+ public string MetadataSeparator { get; }
}
}
diff --git a/src/Dapr.AspNetCore/TopicMetadataAttribute.cs b/src/Dapr.AspNetCore/TopicMetadataAttribute.cs
new file mode 100644
index 00000000..eb3e4009
--- /dev/null
+++ b/src/Dapr.AspNetCore/TopicMetadataAttribute.cs
@@ -0,0 +1,62 @@
+// ------------------------------------------------------------------------
+// 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
+{
+ using System;
+
+ ///
+ /// IOriginalTopicMetadata that describes subscribe endpoint to a topic original metadata.
+ ///
+ [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
+ public class TopicMetadataAttribute : Attribute, IOriginalTopicMetadata
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The metadata name.
+ /// The metadata value.
+ public TopicMetadataAttribute(string name, string value)
+ {
+ ArgumentVerifier.ThrowIfNullOrEmpty(name, nameof(name));
+ ArgumentVerifier.ThrowIfNullOrEmpty(value, nameof(value));
+ Name = name;
+ Value = value;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The metadata id.
+ /// The metadata name.
+ /// The metadata value.
+ public TopicMetadataAttribute(string id, string name, string value)
+ {
+ ArgumentVerifier.ThrowIfNullOrEmpty(id, nameof(name));
+ ArgumentVerifier.ThrowIfNullOrEmpty(name, nameof(name));
+ ArgumentVerifier.ThrowIfNullOrEmpty(value, nameof(value));
+ Id = id;
+ Name = name;
+ Value = value;
+ }
+
+ ///
+ public string Id { get; }
+
+ ///
+ public string Name { get; }
+
+ ///
+ public string Value { get; }
+ }
+}
diff --git a/test/Dapr.AspNetCore.IntegrationTest.App/DaprController.cs b/test/Dapr.AspNetCore.IntegrationTest.App/DaprController.cs
index 2a0c8dbd..960872be 100644
--- a/test/Dapr.AspNetCore.IntegrationTest.App/DaprController.cs
+++ b/test/Dapr.AspNetCore.IntegrationTest.App/DaprController.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
// 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.
@@ -68,6 +68,16 @@ namespace Dapr.AspNetCore.IntegrationTest.App
{
}
+ [Topic("pubsub", "metadata", new string[1] { "id1" })]
+ [Topic("pubsub", "metadata.1", true)]
+ [HttpPost("/multiMetadataTopicAttr")]
+ [TopicMetadata("n1", "v1")]
+ [TopicMetadata("id1", "n2", "v2")]
+ [TopicMetadata("id1", "n2", "v3")]
+ public void MultipleMetadataTopics()
+ {
+ }
+
[Topic("pubsub", "splitTopicAttr", true)]
[HttpPost("/splitTopics")]
public void SplitTopic()
@@ -112,7 +122,7 @@ namespace Dapr.AspNetCore.IntegrationTest.App
}
[HttpPost("/echo-user")]
- public ActionResult EchoUser([FromQuery]UserInfo user)
+ public ActionResult EchoUser([FromQuery] UserInfo user)
{
// To simulate an action where there's no Dapr attribute, yet MVC still checks the list of available model binder providers.
return user;
diff --git a/test/Dapr.AspNetCore.IntegrationTest.App/Startup.cs b/test/Dapr.AspNetCore.IntegrationTest.App/Startup.cs
index 201ba7b5..e776fa46 100644
--- a/test/Dapr.AspNetCore.IntegrationTest.App/Startup.cs
+++ b/test/Dapr.AspNetCore.IntegrationTest.App/Startup.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
// 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.
@@ -66,6 +66,8 @@ namespace Dapr.AspNetCore.IntegrationTest.App
endpoints.MapPost("/splitTopics", context => Task.CompletedTask).WithTopic("pubsub", "splitTopicBuilder");
+ endpoints.MapPost("/splitMetadataTopics", context => Task.CompletedTask).WithTopic("pubsub", "splitMetadataTopicBuilder", new Dictionary { { "n1", "v1" }, { "n2", "v1" } });
+
endpoints.MapPost("/routingwithstateentry/{widget}", async context =>
{
var daprClient = context.RequestServices.GetRequiredService();
diff --git a/test/Dapr.AspNetCore.IntegrationTest/SubscribeEndpointTest.cs b/test/Dapr.AspNetCore.IntegrationTest/SubscribeEndpointTest.cs
index 128c81b3..881a015f 100644
--- a/test/Dapr.AspNetCore.IntegrationTest/SubscribeEndpointTest.cs
+++ b/test/Dapr.AspNetCore.IntegrationTest/SubscribeEndpointTest.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
// 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.
@@ -14,9 +14,9 @@
namespace Dapr.AspNetCore.IntegrationTest
{
using System.Collections.Generic;
+ using System.Linq;
using System.Net.Http;
using System.Text.Json;
- using System.Text.Json.Serialization;
using System.Threading.Tasks;
using FluentAssertions;
using Xunit;
@@ -39,21 +39,38 @@ namespace Dapr.AspNetCore.IntegrationTest
var json = await JsonSerializer.DeserializeAsync(stream);
json.ValueKind.Should().Be(JsonValueKind.Array);
- json.GetArrayLength().Should().Be(12);
- var subscriptions = new List<(string PubsubName, string Topic, string Route, string rawPayload, string match)>();
+ json.GetArrayLength().Should().Be(15);
+ var subscriptions = new List<(string PubsubName, string Topic, string Route, string rawPayload, string match, string metadata)>();
foreach (var element in json.EnumerateArray())
{
var pubsubName = element.GetProperty("pubsubName").GetString();
var topic = element.GetProperty("topic").GetString();
var rawPayload = string.Empty;
+ Dictionary originalMetadata = new Dictionary();
if (element.TryGetProperty("metadata", out JsonElement metadata))
{
- rawPayload = metadata.GetProperty("rawPayload").GetString();
+ if (metadata.TryGetProperty("rawPayload", out JsonElement rawPayloadJson))
+ {
+ rawPayload = rawPayloadJson.GetString();
+ }
+
+ foreach (var originalMetadataProperty in metadata.EnumerateObject().OrderBy(c=>c.Name))
+ {
+ if (!originalMetadataProperty.Name.Equals("rawPayload"))
+ {
+ originalMetadata.Add(originalMetadataProperty.Name, originalMetadataProperty.Value.GetString());
+ }
+ }
+ }
+ var originalMetadataString= string.Empty;
+ if (originalMetadata.Count > 0)
+ {
+ originalMetadataString = string.Join(";", originalMetadata.Select(c => $"{c.Key}={c.Value}"));
}
if (element.TryGetProperty("route", out JsonElement route))
{
- subscriptions.Add((pubsubName, topic, route.GetString(), rawPayload, string.Empty));
+ subscriptions.Add((pubsubName, topic, route.GetString(), rawPayload, string.Empty, originalMetadataString));
}
else if (element.TryGetProperty("routes", out JsonElement routes))
{
@@ -63,30 +80,33 @@ namespace Dapr.AspNetCore.IntegrationTest
{
var match = rule.GetProperty("match").GetString();
var path = rule.GetProperty("path").GetString();
- subscriptions.Add((pubsubName, topic, path, rawPayload, match));
+ subscriptions.Add((pubsubName, topic, path, rawPayload, match, originalMetadataString));
}
}
if (routes.TryGetProperty("default", out JsonElement defaultProperty))
{
- subscriptions.Add((pubsubName, topic, defaultProperty.GetString(), rawPayload, string.Empty));
- }
+ subscriptions.Add((pubsubName, topic, defaultProperty.GetString(), rawPayload, string.Empty, originalMetadataString));
+ }
}
}
- subscriptions.Should().Contain(("testpubsub", "A", "topic-a", string.Empty, string.Empty));
- subscriptions.Should().Contain(("testpubsub", "A.1", "topic-a", string.Empty, string.Empty));
- subscriptions.Should().Contain(("pubsub", "B", "B", string.Empty, string.Empty));
- subscriptions.Should().Contain(("custom-pubsub", "custom-C", "C", string.Empty, string.Empty));
- subscriptions.Should().Contain(("pubsub", "register-user", "register-user", string.Empty, string.Empty));
- subscriptions.Should().Contain(("pubsub", "register-user-plaintext", "register-user-plaintext", string.Empty, string.Empty));
- subscriptions.Should().Contain(("pubsub", "D", "D", "true", string.Empty));
- subscriptions.Should().Contain(("pubsub", "E", "E", string.Empty, string.Empty));
- subscriptions.Should().Contain(("pubsub", "E", "E-Critical", string.Empty, "event.type == \"critical\""));
- subscriptions.Should().Contain(("pubsub", "E", "E-Important", string.Empty, "event.type == \"important\""));
- subscriptions.Should().Contain(("pubsub", "F", "multiTopicAttr", string.Empty, string.Empty));
- subscriptions.Should().Contain(("pubsub", "F.1", "multiTopicAttr", "true", string.Empty));
- subscriptions.Should().Contain(("pubsub", "splitTopicBuilder", "splitTopics", string.Empty, string.Empty));
- subscriptions.Should().Contain(("pubsub", "splitTopicAttr", "splitTopics", "true", string.Empty));
+ subscriptions.Should().Contain(("testpubsub", "A", "topic-a", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("testpubsub", "A.1", "topic-a", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "B", "B", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("custom-pubsub", "custom-C", "C", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "register-user", "register-user", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "register-user-plaintext", "register-user-plaintext", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "D", "D", "true", string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "E", "E", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "E", "E-Critical", string.Empty, "event.type == \"critical\"", string.Empty));
+ subscriptions.Should().Contain(("pubsub", "E", "E-Important", string.Empty, "event.type == \"important\"", string.Empty));
+ subscriptions.Should().Contain(("pubsub", "F", "multiTopicAttr", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "F.1", "multiTopicAttr", "true", string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "splitTopicBuilder", "splitTopics", string.Empty, string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "splitTopicAttr", "splitTopics", "true", string.Empty, string.Empty));
+ subscriptions.Should().Contain(("pubsub", "metadata", "multiMetadataTopicAttr", string.Empty, string.Empty, "n1=v1;n2=v2,v3"));
+ subscriptions.Should().Contain(("pubsub", "metadata.1", "multiMetadataTopicAttr", "true", string.Empty, "n1=v1"));
+ subscriptions.Should().Contain(("pubsub", "splitMetadataTopicBuilder", "splitMetadataTopics", string.Empty, string.Empty, "n1=v1;n2=v1"));
// Test priority route sorting
var eTopic = subscriptions.FindAll(e => e.Topic == "E");