From 3afec71c4e70fa395d5b0d50f58992af133073c8 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 28 Sep 2022 14:25:23 +0800 Subject: [PATCH 1/9] Remove unused methods of `IDaprSerializer`. --- .../Volo/Abp/Dapr/IDaprSerializer.cs | 6 ------ .../Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs | 15 --------------- 2 files changed, 21 deletions(-) diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs index 7eec2c5c1c..c37e9f2407 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs @@ -6,11 +6,5 @@ public interface IDaprSerializer object Deserialize(byte[] value, Type type); - T Deserialize(byte[] value); - - string SerializeToString(object obj); - object Deserialize(string value, Type type); - - T Deserialize(string value); } diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs index ce9b4a8523..cc3bf7f529 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs @@ -23,23 +23,8 @@ public class Utf8JsonDaprSerializer : IDaprSerializer, ITransientDependency return _jsonSerializer.Deserialize(type, Encoding.UTF8.GetString(value)); } - public T Deserialize(byte[] value) - { - return _jsonSerializer.Deserialize(Encoding.UTF8.GetString(value)); - } - - public string SerializeToString(object obj) - { - return _jsonSerializer.Serialize(obj); - } - public object Deserialize(string value, Type type) { return _jsonSerializer.Deserialize(type, value); } - - public T Deserialize(string value) - { - return _jsonSerializer.Deserialize(value); - } } From 707cb6d1057855f0842532a53a8ea7f259fde7ec Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 3 Nov 2022 13:28:15 +0800 Subject: [PATCH 2/9] Allow users to use the standard `Topic` attribute. --- .../AbpDaprEndpointRouteBuilderExtensions.cs | 296 ++++++++++++++++++ ...lo.Abp.AspNetCore.Mvc.Dapr.EventBus.csproj | 2 - .../AbpAspNetCoreMvcDaprEventBusModule.cs | 48 ++- .../AbpAspNetCoreMvcDaprEventBusOptions.cs | 11 - .../AbpAspNetCoreMvcDaprPubSubConsts.cs | 2 - .../AbpAspNetCoreMvcDaprPubSubProvider.cs | 63 ---- ...MvcDaprPubSubProviderContributorContext.cs | 16 - ...> AbpAspNetCoreMvcDaprEventsController.cs} | 13 +- ...NetCoreMvcDaprPubSubProviderContributor.cs | 6 - ...AspNetCoreMvcDaprSubscriptionDefinition.cs | 10 - ...AspNetCoreMvcDaprPubSubJsonNamingPolicy.cs | 11 - ...eMvcDaprSubscriptionDefinitionConverter.cs | 25 -- .../Volo.Abp.AspNetCore.Mvc.Dapr.csproj | 4 +- .../Mvc/Dapr/DaprAppApiTokenValidator.cs | 41 +-- .../Mvc/Dapr/DaprHttpContextExtensions.cs | 27 +- .../Mvc/Dapr/IDaprAppApiTokenValidator.cs | 12 +- .../src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj | 4 +- .../Volo/Abp/Dapr/AbpDaprClientFactory.cs | 23 +- .../Volo/Abp/Dapr/AbpDaprModule.cs | 13 +- .../Volo/Abp/Dapr/DaprApiTokenProvider.cs | 13 +- .../Volo/Abp/Dapr/IAbpDaprClientFactory.cs | 15 +- .../Volo/Abp/Dapr/IDaprApiTokenProvider.cs | 10 +- .../Volo/Abp/Dapr/IDaprSerializer.cs | 4 +- .../Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs | 3 +- .../Volo.Abp.DistributedLocking.Dapr.csproj | 6 +- .../Dapr/AbpDistributedLockDaprOptions.cs | 10 +- .../Dapr/DaprAbpDistributedLock.cs | 19 +- .../Dapr/DaprAbpDistributedLockHandle.cs | 9 +- .../Volo.Abp.EventBus.Dapr.csproj | 4 +- .../EventBus/Dapr/DaprDistributedEventBus.cs | 14 +- .../Volo.Abp.Http.Client.Dapr.csproj | 4 +- .../Http/Client/Dapr/AbpInvocationHandler.cs | 5 +- 32 files changed, 466 insertions(+), 277 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/DaprAspNetCore/AbpDaprEndpointRouteBuilderExtensions.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusOptions.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProvider.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProviderContributorContext.cs rename framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/{AbpAspNetCoreMvcDaprPubSubController.cs => AbpAspNetCoreMvcDaprEventsController.cs} (75%) delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/IAbpAspNetCoreMvcDaprPubSubProviderContributor.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionDefinition.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprPubSubJsonNamingPolicy.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/DaprAspNetCore/AbpDaprEndpointRouteBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/DaprAspNetCore/AbpDaprEndpointRouteBuilderExtensions.cs new file mode 100644 index 0000000000..b5866c5a68 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/DaprAspNetCore/AbpDaprEndpointRouteBuilderExtensions.cs @@ -0,0 +1,296 @@ +// ------------------------------------------------------------------------ +// 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; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Dapr +{ + /// + /// This class defines configurations for the subscribe endpoint. + /// + public class AbpSubscribeOptions + { + /// + /// Gets or Sets a value which indicates whether to enable or disable processing raw messages. + /// + public bool EnableRawPayload { get; set; } + + /// + /// An optional delegate used to configure the subscriptions. + /// + public Func, Task> SubscriptionsCallback { get; set; } + } + + /// + /// This class defines subscribe endpoint response + /// + public class AbpSubscription + { + /// + /// Gets or sets the topic name. + /// + public string Topic { get; set; } + + /// + /// Gets or sets the pubsub name + /// + public string PubsubName { get; set; } + + /// + /// Gets or sets the route + /// + public string Route { get; set; } + + /// + /// Gets or sets the routes + /// + public AbpRoutes Routes { get; set; } + + /// + /// Gets or sets the metadata. + /// + public AbpMetadata Metadata { get; set; } + + /// + /// Gets or sets the deadletter topic. + /// + public string DeadLetterTopic { get; set; } + } + + /// + /// This class defines the metadata for subscribe endpoint. + /// + public class AbpMetadata : Dictionary + { + /// + /// Initializes a new instance of the Metadata class. + /// + public AbpMetadata() { } + + /// + /// Initializes a new instance of the Metadata class. + /// + /// + public AbpMetadata(IDictionary dictionary) : base(dictionary) { } + + /// + /// RawPayload key + /// + internal const string RawPayload = "rawPayload"; + } + + /// + /// This class defines the routes for subscribe endpoint. + /// + public class AbpRoutes + { + /// + /// Gets or sets the default route + /// + public string Default { get; set; } + + /// + /// Gets or sets the routing rules + /// + public List Rules { get; set; } + } + + /// + /// This class defines the rule for subscribe endpoint. + /// + public class AbpRule + { + /// + /// Gets or sets the CEL expression to match this route. + /// + public string Match { get; set; } + + /// + /// Gets or sets the path of the route. + /// + public string Path { get; set; } + } +} + +namespace Microsoft.AspNetCore.Builder +{ + using System.Collections.Generic; + using System.Linq; + using System.Text.Json; + using System.Text.Json.Serialization; + using Dapr; + using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Routing; + using Microsoft.AspNetCore.Routing.Patterns; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Logging; + + /// + /// Contains extension methods for . + /// + public static class AbpDaprEndpointRouteBuilderExtensions + { + /// + /// Maps an endpoint that will respond to requests to /dapr/subscribe from the + /// Dapr runtime. + /// + /// The . + /// The . + public static IEndpointConventionBuilder MapAbpSubscribeHandler(this IEndpointRouteBuilder endpoints) + { + return CreateSubscribeEndPoint(endpoints); + } + + /// + /// Maps an endpoint that will respond to requests to /dapr/subscribe from the + /// Dapr runtime. + /// + /// The . + /// Configuration options + /// The . + /// + public static IEndpointConventionBuilder MapAbpSubscribeHandler(this IEndpointRouteBuilder endpoints, AbpSubscribeOptions options) + { + return CreateSubscribeEndPoint(endpoints, options); + } + + private static IEndpointConventionBuilder CreateSubscribeEndPoint(IEndpointRouteBuilder endpoints, AbpSubscribeOptions options = null) + { + if (endpoints is null) + { + throw new System.ArgumentNullException(nameof(endpoints)); + } + + return endpoints.MapGet("dapr/subscribe", async context => + { + var logger = context.RequestServices.GetRequiredService().CreateLogger("DaprTopicSubscription"); + var dataSource = context.RequestServices.GetRequiredService(); + var subscriptions = dataSource.Endpoints + .OfType() + .Where(e => e.Metadata.GetOrderedMetadata().Any(t => t.Name != null)) // only endpoints which have TopicAttribute with not null Name. + .SelectMany(e => + { + var topicMetadata = e.Metadata.GetOrderedMetadata(); + var originalTopicMetadata = e.Metadata.GetOrderedMetadata(); + + var subs = new List<(string PubsubName, string Name, string DeadLetterTopic, bool? EnableRawPayload, string Match, int Priority, Dictionary OriginalTopicMetadata, string MetadataSeparator, RoutePattern RoutePattern)>(); + + for (int i = 0; i < topicMetadata.Count(); i++) + { + subs.Add((topicMetadata[i].PubsubName, + topicMetadata[i].Name, + (topicMetadata[i] as IDeadLetterTopicMetadata)?.DeadLetterTopic, + (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)); + } + + return subs; + }) + .Distinct() + .GroupBy(e => new { e.PubsubName, e.Name }) + .Select(e => e.OrderBy(e => e.Priority)) + .Select(e => + { + 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 AbpMetadata(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(AbpMetadata.RawPayload, "true"); + } + + if (logger != null) + { + if (defaultRoutes.Count > 1) + { + logger.LogError("A default subscription to topic {name} on pubsub {pubsub} already exists.", first.Name, first.PubsubName); + } + + var duplicatePriorities = rules.GroupBy(e => e.Priority) + .Where(g => g.Count() > 1) + .ToDictionary(x => x.Key, y => y.Count()); + + foreach (var entry in duplicatePriorities) + { + logger.LogError("A subscription to topic {name} on pubsub {pubsub} has duplicate priorities for {priority}: found {count} occurrences.", first.Name, first.PubsubName, entry.Key, entry.Value); + } + } + + var subscription = new AbpSubscription + { + Topic = first.Name, + PubsubName = first.PubsubName, + Metadata = metadata.Count > 0 ? metadata : null, + }; + + if (first.DeadLetterTopic != null) + { + subscription.DeadLetterTopic = first.DeadLetterTopic; + } + + // Use the V2 routing rules structure + if (rules.Count > 0) + { + subscription.Routes = new AbpRoutes + { + Rules = rules.Select(e => new AbpRule + { + Match = e.Match, + Path = RoutePatternToString(e.RoutePattern), + }).ToList(), + Default = defaultRoute, + }; + } + // Use the V1 structure for backward compatibility. + else + { + subscription.Route = defaultRoute; + } + + return subscription; + }) + .OrderBy(e => (e.PubsubName, e.Topic)) + .ToList(); + + await options?.SubscriptionsCallback(subscriptions); + await context.Response.WriteAsync(JsonSerializer.Serialize(subscriptions, + new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + })); + }); + } + + 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/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.csproj index e1ede9fe69..f31ded0e06 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.csproj @@ -5,8 +5,6 @@ net7.0 - enable - enable diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs index 333a5aae9a..e3c199c001 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs @@ -1,7 +1,15 @@ -using Microsoft.AspNetCore.Http.Json; -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.SystemTextJson; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Dapr; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; using Volo.Abp.EventBus.Dapr; -using Volo.Abp.Json.SystemTextJson; +using Volo.Abp.EventBus.Distributed; using Volo.Abp.Modularity; namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus; @@ -14,16 +22,36 @@ public class AbpAspNetCoreMvcDaprEventBusModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - // TODO: Add NewtonsoftJson json converter. + var subscribeOptions = context.Services.ExecutePreConfiguredActions(); - Configure(options => + Configure(options => { - options.SerializerOptions.Converters.Add(new AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter()); - }); + options.EndpointConfigureActions.Add(endpointContext => + { + var rootServiceProvider = endpointContext.ScopeServiceProvider.GetRequiredService(); + subscribeOptions.SubscriptionsCallback = subscriptions => + { + var daprEventBusOptions = rootServiceProvider.GetRequiredService>().Value; + foreach (var handler in rootServiceProvider.GetRequiredService>().Value.Handlers) + { + foreach (var @interface in handler.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDistributedEventHandler<>))) + { + var eventType = @interface.GetGenericArguments()[0]; + var eventName = EventNameAttribute.GetNameOrDefault(eventType); + subscriptions.Add(new AbpSubscription() + { + PubsubName = daprEventBusOptions.PubSubName, + Topic = eventName, + Route = AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl + }); + } + } - Configure(options => - { - options.JsonSerializerOptions.Converters.Add(new AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter()); + return Task.CompletedTask; + }; + + endpointContext.Endpoints.MapAbpSubscribeHandler(subscribeOptions); + }); }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusOptions.cs deleted file mode 100644 index 02ca4c8e22..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus; - -public class AbpAspNetCoreMvcDaprEventBusOptions -{ - public List Contributors { get; } - - public AbpAspNetCoreMvcDaprEventBusOptions() - { - Contributors = new List(); - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubConsts.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubConsts.cs index e785f2e737..5f224abc7e 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubConsts.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubConsts.cs @@ -2,7 +2,5 @@ public class AbpAspNetCoreMvcDaprPubSubConsts { - public const string DaprSubscribeUrl = "dapr/subscribe"; - public const string DaprEventCallbackUrl = "api/abp/dapr/event"; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProvider.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProvider.cs deleted file mode 100644 index e797bd2fc0..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProvider.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; -using Volo.Abp.DependencyInjection; -using Volo.Abp.EventBus; -using Volo.Abp.EventBus.Dapr; -using Volo.Abp.EventBus.Distributed; - -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus; - -public class AbpAspNetCoreMvcDaprPubSubProvider : ITransientDependency -{ - protected IServiceProvider ServiceProvider { get; } - protected AbpAspNetCoreMvcDaprEventBusOptions AspNetCoreMvcDaprEventBusOptions { get; } - protected AbpDaprEventBusOptions DaprEventBusOptions { get; } - protected AbpDistributedEventBusOptions DistributedEventBusOptions { get; } - - public AbpAspNetCoreMvcDaprPubSubProvider( - IServiceProvider serviceProvider, - IOptions aspNetCoreDaprEventBusOptions, - IOptions daprEventBusOptions, - IOptions distributedEventBusOptions) - { - ServiceProvider = serviceProvider; - AspNetCoreMvcDaprEventBusOptions = aspNetCoreDaprEventBusOptions.Value; - DaprEventBusOptions = daprEventBusOptions.Value; - DistributedEventBusOptions = distributedEventBusOptions.Value; - } - - public virtual async Task> GetSubscriptionsAsync() - { - var subscriptions = new List(); - foreach (var handler in DistributedEventBusOptions.Handlers) - { - foreach (var @interface in handler.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDistributedEventHandler<>))) - { - var eventType = @interface.GetGenericArguments()[0]; - var eventName = EventNameAttribute.GetNameOrDefault(eventType); - - subscriptions.Add(new AbpAspNetCoreMvcDaprSubscriptionDefinition() - { - PubSubName = DaprEventBusOptions.PubSubName, - Topic = eventName, - Route = AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl - }); - } - } - - if (AspNetCoreMvcDaprEventBusOptions.Contributors.Any()) - { - using (var scope = ServiceProvider.CreateScope()) - { - var context = new AbpAspNetCoreMvcDaprPubSubProviderContributorContext(scope.ServiceProvider, subscriptions); - foreach (var contributor in AspNetCoreMvcDaprEventBusOptions.Contributors) - { - await contributor.ContributeAsync(context); - } - } - } - - return subscriptions; - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProviderContributorContext.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProviderContributorContext.cs deleted file mode 100644 index 564b541dec..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProviderContributorContext.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; - -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus; - -public class AbpAspNetCoreMvcDaprPubSubProviderContributorContext -{ - public IServiceProvider ServiceProvider { get; } - - public List Subscriptions { get; } - - public AbpAspNetCoreMvcDaprPubSubProviderContributorContext(IServiceProvider serviceProvider, List daprSubscriptionModels) - { - ServiceProvider = serviceProvider; - Subscriptions = daprSubscriptionModels; - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprPubSubController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs similarity index 75% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprPubSubController.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs index 674e227cd0..92953350ae 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprPubSubController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -10,19 +11,13 @@ namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Controllers; [Area("abp")] [RemoteService(Name = "abp")] -public class AbpAspNetCoreMvcDaprPubSubController : AbpController +public class AbpAspNetCoreMvcDaprEventsController : AbpController { - [HttpGet(AbpAspNetCoreMvcDaprPubSubConsts.DaprSubscribeUrl)] - public virtual async Task> SubscribeAsync() - { - return await HttpContext.RequestServices.GetRequiredService().GetSubscriptionsAsync(); - } - [HttpPost(AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl)] public virtual async Task EventsAsync() { - this.HttpContext.ValidateDaprAppApiToken(); - + await HttpContext.ValidateDaprAppApiTokenAsync(); + var bodyJsonDocument = await JsonDocument.ParseAsync(HttpContext.Request.Body); var request = JsonSerializer.Deserialize(bodyJsonDocument.RootElement.GetRawText(), HttpContext.RequestServices.GetRequiredService>().Value.JsonSerializerOptions); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/IAbpAspNetCoreMvcDaprPubSubProviderContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/IAbpAspNetCoreMvcDaprPubSubProviderContributor.cs deleted file mode 100644 index 87047cd7ec..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/IAbpAspNetCoreMvcDaprPubSubProviderContributor.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus; - -public interface IAbpAspNetCoreMvcDaprPubSubProviderContributor -{ - Task ContributeAsync(AbpAspNetCoreMvcDaprPubSubProviderContributorContext context); -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionDefinition.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionDefinition.cs deleted file mode 100644 index 287e78e01a..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionDefinition.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; - -public class AbpAspNetCoreMvcDaprSubscriptionDefinition -{ - public string PubSubName { get; set; } - - public string Topic { get; set; } - - public string Route { get; set; } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprPubSubJsonNamingPolicy.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprPubSubJsonNamingPolicy.cs deleted file mode 100644 index 0aa6bd4f7c..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprPubSubJsonNamingPolicy.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; - -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.SystemTextJson; - -public class AbpAspNetCoreMvcDaprPubSubJsonNamingPolicy : JsonNamingPolicy -{ - public override string ConvertName(string name) - { - return name.ToLower(); - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter.cs deleted file mode 100644 index bcd2a0e1be..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; - -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.SystemTextJson; - -public class AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter : JsonConverter -{ - private JsonSerializerOptions? _writeJsonSerializerOptions; - - public override AbpAspNetCoreMvcDaprSubscriptionDefinition Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - throw new NotSupportedException(); - } - - public override void Write(Utf8JsonWriter writer, AbpAspNetCoreMvcDaprSubscriptionDefinition value, JsonSerializerOptions options) - { - _writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(new JsonSerializerOptions(options) - { - PropertyNamingPolicy = new AbpAspNetCoreMvcDaprPubSubJsonNamingPolicy() - }, x => x == this); - - JsonSerializer.Serialize(writer, value, _writeJsonSerializerOptions); - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo.Abp.AspNetCore.Mvc.Dapr.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo.Abp.AspNetCore.Mvc.Dapr.csproj index 0c72d5acc5..03bb453ba2 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo.Abp.AspNetCore.Mvc.Dapr.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo.Abp.AspNetCore.Mvc.Dapr.csproj @@ -5,8 +5,6 @@ net7.0 - enable - enable @@ -16,7 +14,7 @@ - + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs index 817eb9824d..90432ebe53 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs @@ -1,5 +1,6 @@ -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.SignalR; +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization; using Volo.Abp.Dapr; @@ -10,22 +11,22 @@ namespace Volo.Abp.AspNetCore.Mvc.Dapr; public class DaprAppApiTokenValidator : IDaprAppApiTokenValidator, ISingletonDependency { protected IHttpContextAccessor HttpContextAccessor { get; } - protected HttpContext HttpContext => GetHttpContext(); + protected HttpContext HttpContext => GetHttpContext(); public DaprAppApiTokenValidator(IHttpContextAccessor httpContextAccessor) { HttpContextAccessor = httpContextAccessor; } - - public virtual void CheckDaprAppApiToken() + + public virtual async Task CheckDaprAppApiTokenAsync() { - var expectedAppApiToken = GetConfiguredAppApiTokenOrNull(); + var expectedAppApiToken = await GetConfiguredAppApiTokenOrNullAsync(); if (expectedAppApiToken.IsNullOrWhiteSpace()) { return; } - - var headerAppApiToken = GetDaprAppApiTokenOrNull(); + + var headerAppApiToken = await GetDaprAppApiTokenOrNullAsync(); if (headerAppApiToken.IsNullOrWhiteSpace()) { throw new AbpAuthorizationException("Expected Dapr App API Token is not provided! Dapr should set the 'dapr-api-token' HTTP header."); @@ -37,39 +38,39 @@ public class DaprAppApiTokenValidator : IDaprAppApiTokenValidator, ISingletonDep } } - public virtual bool IsValidDaprAppApiToken() + public virtual async Task IsValidDaprAppApiTokenAsync() { - var expectedAppApiToken = GetConfiguredAppApiTokenOrNull(); + var expectedAppApiToken = await GetConfiguredAppApiTokenOrNullAsync(); if (expectedAppApiToken.IsNullOrWhiteSpace()) { return true; } - - var headerAppApiToken = GetDaprAppApiTokenOrNull(); + + var headerAppApiToken = await GetDaprAppApiTokenOrNullAsync(); return expectedAppApiToken == headerAppApiToken; } - public virtual string? GetDaprAppApiTokenOrNull() + public virtual Task GetDaprAppApiTokenOrNullAsync() { string apiTokenHeader = HttpContext.Request.Headers["dapr-api-token"]; if (string.IsNullOrEmpty(apiTokenHeader) || apiTokenHeader.Length < 1) { - return null; + return Task.FromResult(null); } - return apiTokenHeader; + return Task.FromResult(apiTokenHeader); } - - protected virtual string? GetConfiguredAppApiTokenOrNull() + + protected virtual async Task GetConfiguredAppApiTokenOrNullAsync() { - return HttpContext + return await HttpContext .RequestServices .GetRequiredService() - .GetAppApiToken(); + .GetAppApiTokenAsync(); } protected virtual HttpContext GetHttpContext() { return HttpContextAccessor.HttpContext ?? throw new AbpException("HttpContext is not available!"); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs index 15663d0c3c..e221af3f4d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs @@ -1,31 +1,32 @@ -using Microsoft.AspNetCore.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.Dapr; public static class DaprHttpContextExtensions { - public static void ValidateDaprAppApiToken(this HttpContext httpContext) + public static async Task ValidateDaprAppApiTokenAsync(this HttpContext httpContext) { - httpContext + await httpContext .RequestServices .GetRequiredService() - .CheckDaprAppApiToken(); + .CheckDaprAppApiTokenAsync(); } - - public static bool IsValidDaprAppApiToken(this HttpContext httpContext) + + public static async Task IsValidDaprAppApiTokenAsync(this HttpContext httpContext) { - return httpContext + return await httpContext .RequestServices .GetRequiredService() - .IsValidDaprAppApiToken(); + .IsValidDaprAppApiTokenAsync(); } - - public static string? GetDaprAppApiTokenOrNull(HttpContext httpContext) + + public static async Task GetDaprAppApiTokenOrNullAsync(HttpContext httpContext) { - return httpContext + return await httpContext .RequestServices .GetRequiredService() - .GetDaprAppApiTokenOrNull(); + .GetDaprAppApiTokenOrNullAsync(); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs index ed5f281ea8..40ed6035cc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs @@ -1,8 +1,12 @@ +using System.Threading.Tasks; + namespace Volo.Abp.AspNetCore.Mvc.Dapr; public interface IDaprAppApiTokenValidator { - void CheckDaprAppApiToken(); - bool IsValidDaprAppApiToken(); - string? GetDaprAppApiTokenOrNull(); -} \ No newline at end of file + Task CheckDaprAppApiTokenAsync(); + + Task IsValidDaprAppApiTokenAsync(); + + Task GetDaprAppApiTokenOrNullAsync(); +} diff --git a/framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj b/framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj index ab079747e9..f21af371bb 100644 --- a/framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj +++ b/framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj @@ -5,8 +5,6 @@ net7.0 - enable - enable @@ -15,7 +13,7 @@ - + diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs index ad284ce156..a2f5069214 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs @@ -1,4 +1,7 @@ -using System.Text.Json; +using System; +using System.Net.Http; +using System.Text.Json; +using System.Threading.Tasks; using Dapr.Client; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -22,7 +25,7 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency JsonSerializerOptions = CreateJsonSerializerOptions(systemTextJsonSerializerOptions.Value); } - public virtual DaprClient Create(Action? builderAction = null) + public virtual async Task CreateAsync(Action builderAction = null) { var builder = new DaprClientBuilder() .UseJsonSerializationOptions(JsonSerializerOptions); @@ -37,7 +40,7 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency builder.UseGrpcEndpoint(DaprOptions.GrpcEndpoint); } - var apiToken = DaprApiTokenProvider.GetDaprApiToken(); + var apiToken = await DaprApiTokenProvider.GetDaprApiTokenAsync(); if (!apiToken.IsNullOrWhiteSpace()) { builder.UseDaprApiToken(apiToken); @@ -48,10 +51,10 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency return builder.Build(); } - public virtual HttpClient CreateHttpClient( - string? appId = null, - string? daprEndpoint = null, - string? daprApiToken = null) + public virtual async Task CreateHttpClientAsync( + string appId = null, + string daprEndpoint = null, + string daprApiToken = null) { if(daprEndpoint.IsNullOrWhiteSpace() && !DaprOptions.HttpEndpoint.IsNullOrWhiteSpace()) @@ -62,12 +65,12 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency return DaprClient.CreateInvokeHttpClient( appId, daprEndpoint, - daprApiToken ?? DaprApiTokenProvider.GetDaprApiToken() + daprApiToken ?? await DaprApiTokenProvider.GetDaprApiTokenAsync() ); } - + protected virtual JsonSerializerOptions CreateJsonSerializerOptions(AbpSystemTextJsonSerializerOptions systemTextJsonSerializerOptions) { return new JsonSerializerOptions(systemTextJsonSerializerOptions.JsonSerializerOptions); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs index 276e96895d..0434332785 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs @@ -1,4 +1,7 @@ -using Microsoft.Extensions.Configuration; +using System; +using System.Threading.Tasks; +using Dapr.Client; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Json; @@ -12,14 +15,8 @@ public class AbpDaprModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); - - ConfigureDaprOptions(configuration); - context.Services.TryAddSingleton( - serviceProvider => serviceProvider - .GetRequiredService() - .Create() - ); + ConfigureDaprOptions(configuration); } private void ConfigureDaprOptions(IConfiguration configuration) diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs index 9fbed78204..982b8f26f1 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -11,14 +12,14 @@ public class DaprApiTokenProvider : IDaprApiTokenProvider, ISingletonDependency { Options = options.Value; } - - public virtual string? GetDaprApiToken() + + public virtual Task GetDaprApiTokenAsync() { - return Options.DaprApiToken; + return Task.FromResult(Options.DaprApiToken); } - public virtual string? GetAppApiToken() + public virtual Task GetAppApiTokenAsync() { - return Options.AppApiToken; + return Task.FromResult(Options.AppApiToken); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs index fc50a07d41..19a42219ad 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs @@ -1,14 +1,17 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; using Dapr.Client; namespace Volo.Abp.Dapr; public interface IAbpDaprClientFactory { - DaprClient Create(Action? builderAction = null); + Task CreateAsync(Action builderAction = null); - HttpClient CreateHttpClient( - string? appId = null, - string? daprEndpoint = null, - string? daprApiToken = null + Task CreateHttpClientAsync( + string appId = null, + string daprEndpoint = null, + string daprApiToken = null ); -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs index 89ea4d516d..d25cf455d9 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs @@ -1,8 +1,10 @@ +using System.Threading.Tasks; + namespace Volo.Abp.Dapr; public interface IDaprApiTokenProvider { - string? GetDaprApiToken(); - - string? GetAppApiToken(); -} \ No newline at end of file + Task GetDaprApiTokenAsync(); + + Task GetAppApiTokenAsync(); +} diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs index c37e9f2407..9a8b4c9520 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs @@ -1,4 +1,6 @@ -namespace Volo.Abp.Dapr; +using System; + +namespace Volo.Abp.Dapr; public interface IDaprSerializer { diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs index cc3bf7f529..c0924f775b 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs @@ -1,4 +1,5 @@ -using System.Text; +using System; +using System.Text; using Volo.Abp.DependencyInjection; using Volo.Abp.Json; diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj index 4adc11cef7..79d39eedf0 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj @@ -2,11 +2,9 @@ - + net7.0 - enable - enable @@ -14,5 +12,5 @@ - + diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs index 7579796871..a51ed8ede7 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs @@ -1,15 +1,17 @@ -namespace Volo.Abp.DistributedLocking.Dapr; +using System; + +namespace Volo.Abp.DistributedLocking.Dapr; public class AbpDistributedLockDaprOptions { public string StoreName { get; set; } - + public string? Owner { get; set; } - + public TimeSpan DefaultExpirationTimeout { get; set; } public AbpDistributedLockDaprOptions() { DefaultExpirationTimeout = TimeSpan.FromMinutes(2); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs index ef99b52227..9bca2def67 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs @@ -1,4 +1,7 @@ -using Microsoft.Extensions.Options; +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; using Volo.Abp.Dapr; using Volo.Abp.DependencyInjection; @@ -10,7 +13,7 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency protected IAbpDaprClientFactory DaprClientFactory { get; } protected AbpDistributedLockDaprOptions DistributedLockDaprOptions { get; } protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; } - + public DaprAbpDistributedLock( IAbpDaprClientFactory daprClientFactory, IOptions distributedLockDaprOptions, @@ -20,18 +23,18 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency DistributedLockKeyNormalizer = distributedLockKeyNormalizer; DistributedLockDaprOptions = distributedLockDaprOptions.Value; } - - public async Task TryAcquireAsync( + + public async Task TryAcquireAsync( string name, TimeSpan timeout = default, CancellationToken cancellationToken = default) { name = DistributedLockKeyNormalizer.NormalizeKey(name); - var daprClient = DaprClientFactory.Create(); + var daprClient = await DaprClientFactory.CreateAsync(); var lockResponse = await daprClient.Lock( - DistributedLockDaprOptions.StoreName, - name, + DistributedLockDaprOptions.StoreName, + name, DistributedLockDaprOptions.Owner ?? Guid.NewGuid().ToString(), (int)DistributedLockDaprOptions.DefaultExpirationTimeout.TotalSeconds, cancellationToken); @@ -43,4 +46,4 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency return new DaprAbpDistributedLockHandle(lockResponse); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLockHandle.cs b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLockHandle.cs index b10f0f3672..ccb82fc995 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLockHandle.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLockHandle.cs @@ -1,18 +1,19 @@ -using Dapr.Client; +using System.Threading.Tasks; +using Dapr.Client; namespace Volo.Abp.DistributedLocking.Dapr; public class DaprAbpDistributedLockHandle : IAbpDistributedLockHandle { protected TryLockResponse LockResponse { get; } - + public DaprAbpDistributedLockHandle(TryLockResponse lockResponse) { LockResponse = lockResponse; } - + public async ValueTask DisposeAsync() { await LockResponse.DisposeAsync(); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.EventBus.Dapr/Volo.Abp.EventBus.Dapr.csproj b/framework/src/Volo.Abp.EventBus.Dapr/Volo.Abp.EventBus.Dapr.csproj index 95cd73dbfd..61f398fecf 100644 --- a/framework/src/Volo.Abp.EventBus.Dapr/Volo.Abp.EventBus.Dapr.csproj +++ b/framework/src/Volo.Abp.EventBus.Dapr/Volo.Abp.EventBus.Dapr.csproj @@ -2,11 +2,9 @@ - + net7.0 - enable - enable diff --git a/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs index c8d47f6887..7f3253d41e 100644 --- a/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs @@ -1,4 +1,8 @@ -using System.Collections.Concurrent; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.Dapr; @@ -113,7 +117,7 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear()); } - protected async override Task PublishToEventBusAsync(Type eventType, object eventData) + protected override async Task PublishToEventBusAsync(Type eventType, object eventData) { await PublishToDaprAsync(eventType, eventData); } @@ -135,12 +139,12 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend return handlerFactoryList.ToArray(); } - public async override Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig) + public override async Task PublishFromOutboxAsync(OutgoingEventInfo outgoingEvent, OutboxConfig outboxConfig) { await PublishToDaprAsync(outgoingEvent.EventName, Serializer.Deserialize(outgoingEvent.EventData, GetEventType(outgoingEvent.EventName))); } - public async override Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig) + public override async Task PublishManyFromOutboxAsync(IEnumerable outgoingEvents, OutboxConfig outboxConfig) { var outgoingEventArray = outgoingEvents.ToArray(); @@ -197,7 +201,7 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend protected virtual async Task PublishToDaprAsync(string eventName, object eventData) { - var client = DaprClientFactory.Create(); + var client = await DaprClientFactory.CreateAsync(); await client.PublishEventAsync(pubsubName: DaprEventBusOptions.PubSubName, topicName: eventName, data: eventData); } diff --git a/framework/src/Volo.Abp.Http.Client.Dapr/Volo.Abp.Http.Client.Dapr.csproj b/framework/src/Volo.Abp.Http.Client.Dapr/Volo.Abp.Http.Client.Dapr.csproj index 610203dae5..0d22e68b97 100644 --- a/framework/src/Volo.Abp.Http.Client.Dapr/Volo.Abp.Http.Client.Dapr.csproj +++ b/framework/src/Volo.Abp.Http.Client.Dapr/Volo.Abp.Http.Client.Dapr.csproj @@ -2,11 +2,9 @@ - + net7.0 - enable - enable diff --git a/framework/src/Volo.Abp.Http.Client.Dapr/Volo/Abp/Http/Client/Dapr/AbpInvocationHandler.cs b/framework/src/Volo.Abp.Http.Client.Dapr/Volo/Abp/Http/Client/Dapr/AbpInvocationHandler.cs index e13c6dbb04..9ebfb5665d 100644 --- a/framework/src/Volo.Abp.Http.Client.Dapr/Volo/Abp/Http/Client/Dapr/AbpInvocationHandler.cs +++ b/framework/src/Volo.Abp.Http.Client.Dapr/Volo/Abp/Http/Client/Dapr/AbpInvocationHandler.cs @@ -1,4 +1,5 @@ -using Dapr.Client; +using System; +using Dapr.Client; using Microsoft.Extensions.Options; using Volo.Abp.Dapr; using Volo.Abp.DependencyInjection; @@ -14,4 +15,4 @@ public class AbpInvocationHandler : InvocationHandler, ITransientDependency DaprEndpoint = daprOptions.Value.HttpEndpoint; } } -} \ No newline at end of file +} From cc92a2fe59109b4e5e848d9855623f66842974a1 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 3 Nov 2022 18:05:57 +0800 Subject: [PATCH 3/9] Add JSON converter and update documents. --- docs/en/Dapr/Index.md | 38 ++++------------ docs/zh-Hans/Dapr/Index.md | 40 +++++------------ .../AbpAspNetCoreMvcDaprEventBusModule.cs | 18 +++++++- .../AbpAspNetCoreMvcDaprEventsController.cs | 40 ++++++++++++----- .../AbpDaprSubscriptionRequestConverter.cs | 44 +++++++++++++++++++ ...DaprSubscriptionRequestConverterFactory.cs | 33 ++++++++++++++ ...DaprSubscriptionRequestJsonNamingPolicy.cs | 11 +++++ ...quest.cs => AbpDaprSubscriptionRequest.cs} | 5 ++- 8 files changed, 157 insertions(+), 72 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverter.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverterFactory.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestJsonNamingPolicy.cs rename framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/{AbpAspNetCoreMvcDaprSubscriptionRequest.cs => AbpDaprSubscriptionRequest.cs} (60%) diff --git a/docs/en/Dapr/Index.md b/docs/en/Dapr/Index.md index 2596c449d1..20abaa3f31 100644 --- a/docs/en/Dapr/Index.md +++ b/docs/en/Dapr/Index.md @@ -62,27 +62,6 @@ Alternatively, you can configure the options in the `Dapr` section of your `apps ### Injecting DaprClient -ABP registers the `DaprClient` class to the [dependency injection](../Dependency-Injection.md) system. So, you can inject and use it whenever you need: - -````csharp -public class MyService : ITransientDependency -{ - private readonly DaprClient _daprClient; - - public MyService(DaprClient daprClient) - { - _daprClient = daprClient; - } - - public async Task DoItAsync() - { - // TODO: Use the injected _daprClient object - } -} -```` - -Injecting `DaprClient` is the recommended way of using it in your application code. When you inject it, the `IAbpDaprClientFactory` service is used to create it, which is explained in the next section. - ### IAbpDaprClientFactory `IAbpDaprClientFactory` can be used to create `DaprClient` or `HttpClient` objects to perform operations on Dapr. It uses `AbpDaprOptions`, so you can configure the settings in a central place. @@ -209,7 +188,7 @@ ABP provides the following endpoints to receive events from Dapr: * `dapr/subscribe`: Dapr uses this endpoint to get a list of subscriptions from the application. ABP automatically returns all the subscriptions for your distributed event handler classes and custom controller actions with the `Topic` attribute. * `api/abp/dapr/event`: The unified endpoint to receive all the events from Dapr. ABP dispatches the events to your event handlers based on the topic name. -> **Since ABP provides the standard `dapr/subscribe` endpoint, you should not manually call the `app.MapSubscribeHandler()` method of Dapr.** You can use the `app.UseCloudEvents()` middleware in your ASP.NET Core pipeline if you want to support the [CloudEvents](https://cloudevents.io/) standard. +> **Since ABP will call `MapSubscribeHandler` internally, you should not manually call it anymore.** You can use the `app.UseCloudEvents()` middleware in your ASP.NET Core pipeline if you want to support the [CloudEvents](https://cloudevents.io/) standard. ### Usage @@ -270,15 +249,18 @@ In addition to ABP's standard distributed event bus system, you can also use Dap ````csharp public class MyService : ITransientDependency { - private readonly DaprClient _daprClient; + private readonly IAbpDaprClientFactory _daprClientFactory; - public MyService(DaprClient daprClient) + public MyService(IAbpDaprClientFactory daprClientFactory) { - _daprClient = daprClient; + _daprClientFactory = daprClientFactory; } public async Task DoItAsync() { + // Create a DaprClient object with default options + DaprClient _daprClient = await _daprClientFactory.CreateAsync(); + await _daprClient.PublishEventAsync( "pubsub", // pubsub name "StockChanged", // topic name @@ -299,8 +281,7 @@ public class MyController : AbpController { [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] - public async Task TestRouteAsync( - [FromBody] StockCountChangedEto model) + public async Task TestRouteAsync([FromBody] AbpDaprSubscriptionRequest model) { HttpContext.ValidateDaprAppApiToken(); @@ -430,8 +411,7 @@ public class MyController : AbpController { [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] - public async Task TestRouteAsync( - [FromBody] StockCountChangedEto model) + public async Task TestRouteAsync([FromBody] AbpDaprSubscriptionRequest model) { // Validate the App API token! HttpContext.ValidateDaprAppApiToken(); diff --git a/docs/zh-Hans/Dapr/Index.md b/docs/zh-Hans/Dapr/Index.md index 30936eb6da..efeb6ca770 100644 --- a/docs/zh-Hans/Dapr/Index.md +++ b/docs/zh-Hans/Dapr/Index.md @@ -62,27 +62,6 @@ Configure(options => ### 注入DaprClient -ABP 将 `DaprClient` 类注册到 [依赖注入](../Dependency-Injection.md) 系统中.因此,你可以在需要时注入并使用它: - -````csharp -public class MyService : ITransientDependency -{ - private readonly DaprClient _daprClient; - - public MyService(DaprClient daprClient) - { - _daprClient = daprClient; - } - - public async Task DoItAsync() - { - // TODO: Use the injected _daprClient object - } -} -```` - -注入 `DaprClient` 是在应用程序代码中使用它的推荐方法.当你注入它时,将使用 `IAbpDaprClientFactory` 服务创建它,这会在下一节中将进行说明. - ### IAbpDaprClientFactory `IAbpDaprClientFactory` 可用于创建 `DaprClient` 或 `HttpClient` 对象来执行对 Dapr 的操作.它使用 `AbpDaprOptions`,因此你可以配置设置. @@ -209,7 +188,7 @@ ABP提供了以下端点来接收来自Dapr的事件: * `dapr/subscribe`: Dapr使用此端点从应用程序获取订阅列表.ABP会自动返回所有分布式事件处理程序类和具有`Topic`属性的自定义控制器操作的订阅. * `api/abp/dapr/event`: 用于接收来自Dapr的所有事件的统一端点.ABP根据主题名称将事件分派给您的事件处理程序. -> **由于ABP提供了标准的`dapr/subscribe`端点,所以你不应该手动调用Dapr的`app.MapSubscribeHandler()`方法.** 如果你想支持[CloudEvents](https://cloudevents.io/)标准,你可以在你的ASP.NET Core管道中使用`app.UseCloudEvents()`中间件. +> **由于ABP会在内部调用`MapSubscribeHandler` 方法,所以你不应该手动调用了.** 如果你想支持[CloudEvents](https://cloudevents.io/)标准,你可以在你的ASP.NET Core管道中使用`app.UseCloudEvents()`中间件. ### 用法 @@ -270,16 +249,19 @@ public class MyHandler : ````csharp public class MyService : ITransientDependency { - private readonly DaprClient _daprClient; + private readonly IAbpDaprClientFactory _daprClientFactory; - public MyService(DaprClient daprClient) + public MyService(IAbpDaprClientFactory daprClientFactory) { - _daprClient = daprClient; + _daprClientFactory = daprClientFactory; } public async Task DoItAsync() { - await _daprClient.PublishEventAsync( + // Create a DaprClient object with default options + DaprClient daprClient = await _daprClientFactory.CreateAsync(); + + await daprClient.PublishEventAsync( "pubsub", // pubsub name "StockChanged", // topic name new StockCountChangedEto // event data @@ -299,8 +281,7 @@ public class MyController : AbpController { [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] - public async Task TestRouteAsync( - [FromBody] StockCountChangedEto model) + public async Task TestRouteAsync([FromBody] AbpDaprSubscriptionRequest model) { HttpContext.ValidateDaprAppApiToken(); @@ -430,8 +411,7 @@ public class MyController : AbpController { [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] - public async Task TestRouteAsync( - [FromBody] StockCountChangedEto model) + public async Task TestRouteAsync([FromBody] AbpDaprSubscriptionRequest model) { // Validate the App API token! HttpContext.ValidateDaprAppApiToken(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs index e3c199c001..ef5594f2c5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs @@ -1,11 +1,14 @@ -using System.Collections.Generic; +using System; using System.Linq; using System.Threading.Tasks; using Dapr; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; +using Volo.Abp.Dapr; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus; using Volo.Abp.EventBus.Dapr; @@ -22,6 +25,12 @@ public class AbpAspNetCoreMvcDaprEventBusModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { + context.Services.AddOptions() + .Configure((options, serviceProvider) => + { + options.JsonSerializerOptions.Converters.Add(new AbpDaprSubscriptionRequestConverterFactory(serviceProvider.GetRequiredService())); + }); + var subscribeOptions = context.Services.ExecutePreConfiguredActions(); Configure(options => @@ -38,6 +47,13 @@ public class AbpAspNetCoreMvcDaprEventBusModule : AbpModule { var eventType = @interface.GetGenericArguments()[0]; var eventName = EventNameAttribute.GetNameOrDefault(eventType); + + if (subscriptions.Any(x => x.PubsubName == daprEventBusOptions.PubSubName && x.Topic == eventName)) + { + // Controllers with a [Topic] attribute can replace built-in event handlers. + continue; + } + subscriptions.Add(new AbpSubscription() { PubsubName = daprEventBusOptions.PubSubName, diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs index 92953350ae..fdfad1d722 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs @@ -1,8 +1,10 @@ -using System.Text.Json; +using System.Collections.Concurrent; +using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Logging; +using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; using Volo.Abp.Dapr; using Volo.Abp.EventBus.Dapr; @@ -14,20 +16,36 @@ namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Controllers; public class AbpAspNetCoreMvcDaprEventsController : AbpController { [HttpPost(AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl)] - public virtual async Task EventsAsync() + public virtual async Task EventAsync() { await HttpContext.ValidateDaprAppApiTokenAsync(); - var bodyJsonDocument = await JsonDocument.ParseAsync(HttpContext.Request.Body); - var request = JsonSerializer.Deserialize(bodyJsonDocument.RootElement.GetRawText(), - HttpContext.RequestServices.GetRequiredService>().Value.JsonSerializerOptions); - - var distributedEventBus = HttpContext.RequestServices.GetRequiredService(); var daprSerializer = HttpContext.RequestServices.GetRequiredService(); + var request = (await JsonDocument.ParseAsync(HttpContext.Request.Body)).Deserialize>(CreateJsonSerializerOptions(daprSerializer)); + if (request != null && request.Data is JsonElement jsonElement) + { + var distributedEventBus = HttpContext.RequestServices.GetRequiredService(); + var eventData = daprSerializer.Deserialize(jsonElement.GetRawText(), distributedEventBus.GetEventType(request.Topic)); + await distributedEventBus.TriggerHandlersAsync(distributedEventBus.GetEventType(request.Topic), eventData); + return Ok(); + } + + Logger.LogError("Invalid Dapr event request."); + return BadRequest(); + } - var eventData = daprSerializer.Deserialize(bodyJsonDocument.RootElement.GetProperty("data").GetRawText(), distributedEventBus.GetEventType(request.Topic)); - await distributedEventBus.TriggerHandlersAsync(distributedEventBus.GetEventType(request.Topic), eventData); + private static readonly ConcurrentDictionary JsonSerializerOptionsCache = new ConcurrentDictionary(); - return Ok(); + protected virtual JsonSerializerOptions CreateJsonSerializerOptions(IDaprSerializer daprSerializer) + { + return JsonSerializerOptionsCache.GetOrAdd(nameof(AbpAspNetCoreMvcDaprEventsController), _ => + { + var settings = new JsonSerializerOptions(JsonSerializerDefaults.Web) + { + PropertyNamingPolicy = new AbpDaprSubscriptionRequestJsonNamingPolicy() + }; + settings.Converters.Add(new AbpDaprSubscriptionRequestConverterFactory(daprSerializer)); + return settings; + }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverter.cs new file mode 100644 index 0000000000..b0a4f72b12 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverter.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; +using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; +using Volo.Abp.Dapr; + +namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; + +public class AbpDaprSubscriptionRequestConverter : JsonConverter> + where T : class +{ + private JsonSerializerOptions _readJsonSerializerOptions; + + private readonly IDaprSerializer _daprSerializer; + + public AbpDaprSubscriptionRequestConverter(IDaprSerializer daprSerializer) + { + _daprSerializer = daprSerializer; + } + + public override AbpDaprSubscriptionRequest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + _readJsonSerializerOptions ??= CreateJsonSerializerOptions(options); + + var rootElement = JsonDocument.ParseValue(ref reader).RootElement; + var obj = JsonSerializer.Deserialize>(rootElement.GetRawText(), _readJsonSerializerOptions); + obj.Data = _daprSerializer.Deserialize(rootElement.GetProperty("data").GetRawText(), typeof(T)).As(); + return obj; + } + + public override void Write(Utf8JsonWriter writer, AbpDaprSubscriptionRequest value, JsonSerializerOptions options) + { + throw new NotSupportedException(); + } + + private JsonSerializerOptions CreateJsonSerializerOptions(JsonSerializerOptions options) + { + var newOptions = new JsonSerializerOptions(options); + newOptions.Converters.RemoveAll(x => x == this || x.GetType() == typeof(AbpDaprSubscriptionRequestConverterFactory)); + newOptions.PropertyNamingPolicy = new AbpDaprSubscriptionRequestJsonNamingPolicy(); + return newOptions; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverterFactory.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverterFactory.cs new file mode 100644 index 0000000000..ec809c23d2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverterFactory.cs @@ -0,0 +1,33 @@ +using System; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; +using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; +using Volo.Abp.Dapr; + +namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; + +public class AbpDaprSubscriptionRequestConverterFactory : JsonConverterFactory +{ + private readonly IDaprSerializer _daprSerializer; + + public AbpDaprSubscriptionRequestConverterFactory(IDaprSerializer daprSerializer) + { + _daprSerializer = daprSerializer; + } + + public override bool CanConvert(Type typeToConvert) + { + return typeToConvert.GetGenericTypeDefinition() == typeof(AbpDaprSubscriptionRequest<>); + } + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + return (JsonConverter)Activator.CreateInstance( + typeof(AbpDaprSubscriptionRequestConverter<>).MakeGenericType(typeToConvert.GetGenericArguments()[0]), + BindingFlags.Instance | BindingFlags.Public, + binder: null, + new object[] { _daprSerializer }, + culture: null)!; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestJsonNamingPolicy.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestJsonNamingPolicy.cs new file mode 100644 index 0000000000..89437f5fa3 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestJsonNamingPolicy.cs @@ -0,0 +1,11 @@ +using System.Text.Json; + +namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; + +public class AbpDaprSubscriptionRequestJsonNamingPolicy : JsonNamingPolicy +{ + public override string ConvertName(string name) + { + return name.ToLower(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionRequest.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpDaprSubscriptionRequest.cs similarity index 60% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionRequest.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpDaprSubscriptionRequest.cs index 46c04b5a44..ccf3724579 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionRequest.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpDaprSubscriptionRequest.cs @@ -1,8 +1,11 @@ namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; -public class AbpAspNetCoreMvcDaprSubscriptionRequest +public class AbpDaprSubscriptionRequest + where T : class { public string PubSubName { get; set; } public string Topic { get; set; } + + public T Data { get; set; } } From 095c6f7b841652b7b8c5277aad1989294789743a Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 7 Nov 2022 09:16:01 +0800 Subject: [PATCH 4/9] Change async methods to sync. --- .../AbpAspNetCoreMvcDaprEventsController.cs | 2 +- .../Mvc/Dapr/DaprAppApiTokenValidator.cs | 24 +++++++++---------- .../Mvc/Dapr/DaprHttpContextExtensions.cs | 18 +++++++------- .../Mvc/Dapr/IDaprAppApiTokenValidator.cs | 8 +++---- .../Volo/Abp/Dapr/AbpDaprClientFactory.cs | 9 ++++--- .../Volo/Abp/Dapr/AbpDaprModule.cs | 8 +++++-- .../Volo/Abp/Dapr/DaprApiTokenProvider.cs | 9 ++++--- .../Volo/Abp/Dapr/IAbpDaprClientFactory.cs | 5 ++-- .../Volo/Abp/Dapr/IDaprApiTokenProvider.cs | 6 ++--- .../Dapr/DaprAbpDistributedLock.cs | 2 +- .../EventBus/Dapr/DaprDistributedEventBus.cs | 2 +- 11 files changed, 45 insertions(+), 48 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs index fdfad1d722..cb4461dd9c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs @@ -18,7 +18,7 @@ public class AbpAspNetCoreMvcDaprEventsController : AbpController [HttpPost(AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl)] public virtual async Task EventAsync() { - await HttpContext.ValidateDaprAppApiTokenAsync(); + HttpContext.ValidateDaprAppApiToken(); var daprSerializer = HttpContext.RequestServices.GetRequiredService(); var request = (await JsonDocument.ParseAsync(HttpContext.Request.Body)).Deserialize>(CreateJsonSerializerOptions(daprSerializer)); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs index 90432ebe53..dd0c6a5300 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs @@ -18,15 +18,15 @@ public class DaprAppApiTokenValidator : IDaprAppApiTokenValidator, ISingletonDep HttpContextAccessor = httpContextAccessor; } - public virtual async Task CheckDaprAppApiTokenAsync() + public virtual void CheckDaprAppApiToken() { - var expectedAppApiToken = await GetConfiguredAppApiTokenOrNullAsync(); + var expectedAppApiToken = GetConfiguredAppApiTokenOrNull(); if (expectedAppApiToken.IsNullOrWhiteSpace()) { return; } - var headerAppApiToken = await GetDaprAppApiTokenOrNullAsync(); + var headerAppApiToken = GetDaprAppApiTokenOrNull(); if (headerAppApiToken.IsNullOrWhiteSpace()) { throw new AbpAuthorizationException("Expected Dapr App API Token is not provided! Dapr should set the 'dapr-api-token' HTTP header."); @@ -38,35 +38,35 @@ public class DaprAppApiTokenValidator : IDaprAppApiTokenValidator, ISingletonDep } } - public virtual async Task IsValidDaprAppApiTokenAsync() + public virtual bool IsValidDaprAppApiToken() { - var expectedAppApiToken = await GetConfiguredAppApiTokenOrNullAsync(); + var expectedAppApiToken = GetConfiguredAppApiTokenOrNull(); if (expectedAppApiToken.IsNullOrWhiteSpace()) { return true; } - var headerAppApiToken = await GetDaprAppApiTokenOrNullAsync(); + var headerAppApiToken = GetDaprAppApiTokenOrNull(); return expectedAppApiToken == headerAppApiToken; } - public virtual Task GetDaprAppApiTokenOrNullAsync() + public virtual string GetDaprAppApiTokenOrNull() { string apiTokenHeader = HttpContext.Request.Headers["dapr-api-token"]; if (string.IsNullOrEmpty(apiTokenHeader) || apiTokenHeader.Length < 1) { - return Task.FromResult(null); + return null; } - return Task.FromResult(apiTokenHeader); + return apiTokenHeader; } - protected virtual async Task GetConfiguredAppApiTokenOrNullAsync() + protected virtual string GetConfiguredAppApiTokenOrNull() { - return await HttpContext + return HttpContext .RequestServices .GetRequiredService() - .GetAppApiTokenAsync(); + .GetAppApiToken(); } protected virtual HttpContext GetHttpContext() diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs index e221af3f4d..aa81765b12 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs @@ -6,27 +6,27 @@ namespace Volo.Abp.AspNetCore.Mvc.Dapr; public static class DaprHttpContextExtensions { - public static async Task ValidateDaprAppApiTokenAsync(this HttpContext httpContext) + public static void ValidateDaprAppApiToken(this HttpContext httpContext) { - await httpContext + httpContext .RequestServices .GetRequiredService() - .CheckDaprAppApiTokenAsync(); + .CheckDaprAppApiToken(); } - public static async Task IsValidDaprAppApiTokenAsync(this HttpContext httpContext) + public static bool IsValidDaprAppApiToken(this HttpContext httpContext) { - return await httpContext + return httpContext .RequestServices .GetRequiredService() - .IsValidDaprAppApiTokenAsync(); + .IsValidDaprAppApiToken(); } - public static async Task GetDaprAppApiTokenOrNullAsync(HttpContext httpContext) + public static string GetDaprAppApiTokenOrNull(HttpContext httpContext) { - return await httpContext + return httpContext .RequestServices .GetRequiredService() - .GetDaprAppApiTokenOrNullAsync(); + .GetDaprAppApiTokenOrNull(); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs index 40ed6035cc..66fd833b77 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs @@ -1,12 +1,10 @@ -using System.Threading.Tasks; - namespace Volo.Abp.AspNetCore.Mvc.Dapr; public interface IDaprAppApiTokenValidator { - Task CheckDaprAppApiTokenAsync(); + void CheckDaprAppApiToken(); - Task IsValidDaprAppApiTokenAsync(); + bool IsValidDaprAppApiToken(); - Task GetDaprAppApiTokenOrNullAsync(); + string GetDaprAppApiTokenOrNull(); } diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs index a2f5069214..aa14bbe7f2 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs @@ -1,7 +1,6 @@ using System; using System.Net.Http; using System.Text.Json; -using System.Threading.Tasks; using Dapr.Client; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -25,7 +24,7 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency JsonSerializerOptions = CreateJsonSerializerOptions(systemTextJsonSerializerOptions.Value); } - public virtual async Task CreateAsync(Action builderAction = null) + public virtual DaprClient Create(Action builderAction = null) { var builder = new DaprClientBuilder() .UseJsonSerializationOptions(JsonSerializerOptions); @@ -40,7 +39,7 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency builder.UseGrpcEndpoint(DaprOptions.GrpcEndpoint); } - var apiToken = await DaprApiTokenProvider.GetDaprApiTokenAsync(); + var apiToken = DaprApiTokenProvider.GetDaprApiToken(); if (!apiToken.IsNullOrWhiteSpace()) { builder.UseDaprApiToken(apiToken); @@ -51,7 +50,7 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency return builder.Build(); } - public virtual async Task CreateHttpClientAsync( + public virtual HttpClient CreateHttpClient( string appId = null, string daprEndpoint = null, string daprApiToken = null) @@ -65,7 +64,7 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency return DaprClient.CreateInvokeHttpClient( appId, daprEndpoint, - daprApiToken ?? await DaprApiTokenProvider.GetDaprApiTokenAsync() + daprApiToken ?? DaprApiTokenProvider.GetDaprApiToken() ); } diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs index 0434332785..4153ae2ec1 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs @@ -1,6 +1,4 @@ using System; -using System.Threading.Tasks; -using Dapr.Client; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -17,6 +15,12 @@ public class AbpDaprModule : AbpModule var configuration = context.Services.GetConfiguration(); ConfigureDaprOptions(configuration); + + context.Services.TryAddSingleton( + serviceProvider => serviceProvider + .GetRequiredService() + .Create() + ); } private void ConfigureDaprOptions(IConfiguration configuration) diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs index 982b8f26f1..10dd3913ed 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs @@ -1,4 +1,3 @@ -using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; @@ -13,13 +12,13 @@ public class DaprApiTokenProvider : IDaprApiTokenProvider, ISingletonDependency Options = options.Value; } - public virtual Task GetDaprApiTokenAsync() + public virtual string GetDaprApiToken() { - return Task.FromResult(Options.DaprApiToken); + return Options.DaprApiToken; } - public virtual Task GetAppApiTokenAsync() + public virtual string GetAppApiToken() { - return Task.FromResult(Options.AppApiToken); + return Options.AppApiToken; } } diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs index 19a42219ad..65c4e76b7e 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs @@ -1,15 +1,14 @@ using System; using System.Net.Http; -using System.Threading.Tasks; using Dapr.Client; namespace Volo.Abp.Dapr; public interface IAbpDaprClientFactory { - Task CreateAsync(Action builderAction = null); + DaprClient Create(Action builderAction = null); - Task CreateHttpClientAsync( + HttpClient CreateHttpClient( string appId = null, string daprEndpoint = null, string daprApiToken = null diff --git a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs index d25cf455d9..60f2195596 100644 --- a/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs +++ b/framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs @@ -1,10 +1,8 @@ -using System.Threading.Tasks; - namespace Volo.Abp.Dapr; public interface IDaprApiTokenProvider { - Task GetDaprApiTokenAsync(); + string GetDaprApiToken(); - Task GetAppApiTokenAsync(); + string GetAppApiToken(); } diff --git a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs index 9bca2def67..974c6461a6 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs @@ -31,7 +31,7 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency { name = DistributedLockKeyNormalizer.NormalizeKey(name); - var daprClient = await DaprClientFactory.CreateAsync(); + var daprClient = DaprClientFactory.Create(); var lockResponse = await daprClient.Lock( DistributedLockDaprOptions.StoreName, name, diff --git a/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs index 7f3253d41e..a00127ac8c 100644 --- a/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs @@ -201,7 +201,7 @@ public class DaprDistributedEventBus : DistributedEventBusBase, ISingletonDepend protected virtual async Task PublishToDaprAsync(string eventName, object eventData) { - var client = await DaprClientFactory.CreateAsync(); + var client = DaprClientFactory.Create(); await client.PublishEventAsync(pubsubName: DaprEventBusOptions.PubSubName, topicName: eventName, data: eventData); } From d7204df550de2765771d44c2d29c13b8a1afd096 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 7 Nov 2022 14:24:26 +0800 Subject: [PATCH 5/9] Use cloud events. --- docs/en/Dapr/Index.md | 4 +- docs/zh-Hans/Dapr/Index.md | 4 +- .../AbpAspNetCoreMvcDaprEventBusModule.cs | 25 +++++------ .../AbpAspNetCoreMvcDaprEventsController.cs | 39 ++++++---------- .../AbpDaprSubscriptionRequestConverter.cs | 44 ------------------- ...DaprSubscriptionRequestConverterFactory.cs | 33 -------------- ...DaprSubscriptionRequestJsonNamingPolicy.cs | 11 ----- .../Models/AbpDaprSubscriptionRequest.cs | 11 ----- 8 files changed, 28 insertions(+), 143 deletions(-) delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverter.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverterFactory.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestJsonNamingPolicy.cs delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpDaprSubscriptionRequest.cs diff --git a/docs/en/Dapr/Index.md b/docs/en/Dapr/Index.md index 20abaa3f31..5904b85508 100644 --- a/docs/en/Dapr/Index.md +++ b/docs/en/Dapr/Index.md @@ -281,7 +281,7 @@ public class MyController : AbpController { [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] - public async Task TestRouteAsync([FromBody] AbpDaprSubscriptionRequest model) + public async Task TestRouteAsync([FromBody] StockCountChangedEto model) { HttpContext.ValidateDaprAppApiToken(); @@ -411,7 +411,7 @@ public class MyController : AbpController { [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] - public async Task TestRouteAsync([FromBody] AbpDaprSubscriptionRequest model) + public async Task TestRouteAsync([FromBody] StockCountChangedEto model) { // Validate the App API token! HttpContext.ValidateDaprAppApiToken(); diff --git a/docs/zh-Hans/Dapr/Index.md b/docs/zh-Hans/Dapr/Index.md index efeb6ca770..c4306f2c9f 100644 --- a/docs/zh-Hans/Dapr/Index.md +++ b/docs/zh-Hans/Dapr/Index.md @@ -281,7 +281,7 @@ public class MyController : AbpController { [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] - public async Task TestRouteAsync([FromBody] AbpDaprSubscriptionRequest model) + public async Task TestRouteAsync([FromBody] StockCountChangedEto model) { HttpContext.ValidateDaprAppApiToken(); @@ -411,7 +411,7 @@ public class MyController : AbpController { [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] - public async Task TestRouteAsync([FromBody] AbpDaprSubscriptionRequest model) + public async Task TestRouteAsync([FromBody] StockCountChangedEto model) { // Validate the App API token! HttpContext.ValidateDaprAppApiToken(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs index ef5594f2c5..a291c4e769 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs @@ -1,14 +1,10 @@ -using System; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using Dapr; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; -using Volo.Abp.Dapr; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus; using Volo.Abp.EventBus.Dapr; @@ -25,12 +21,6 @@ public class AbpAspNetCoreMvcDaprEventBusModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.AddOptions() - .Configure((options, serviceProvider) => - { - options.JsonSerializerOptions.Converters.Add(new AbpDaprSubscriptionRequestConverterFactory(serviceProvider.GetRequiredService())); - }); - var subscribeOptions = context.Services.ExecutePreConfiguredActions(); Configure(options => @@ -54,12 +44,19 @@ public class AbpAspNetCoreMvcDaprEventBusModule : AbpModule continue; } - subscriptions.Add(new AbpSubscription() + var subscription = new AbpSubscription { PubsubName = daprEventBusOptions.PubSubName, Topic = eventName, - Route = AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl - }); + Route = AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl, + Metadata = new AbpMetadata + { + { + AbpMetadata.RawPayload, "true" + } + } + }; + subscriptions.Add(subscription); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs index cb4461dd9c..92cf41db90 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs @@ -1,11 +1,9 @@ -using System.Collections.Concurrent; +using System; using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; using Volo.Abp.Dapr; using Volo.Abp.EventBus.Dapr; @@ -21,31 +19,20 @@ public class AbpAspNetCoreMvcDaprEventsController : AbpController HttpContext.ValidateDaprAppApiToken(); var daprSerializer = HttpContext.RequestServices.GetRequiredService(); - var request = (await JsonDocument.ParseAsync(HttpContext.Request.Body)).Deserialize>(CreateJsonSerializerOptions(daprSerializer)); - if (request != null && request.Data is JsonElement jsonElement) + var body = (await JsonDocument.ParseAsync(HttpContext.Request.Body)); + + var pubSubName = body.RootElement.GetProperty("pubsubname").GetString(); + var topic = body.RootElement.GetProperty("topic").GetString(); + var data = body.RootElement.GetProperty("data").GetRawText(); + if (pubSubName.IsNullOrWhiteSpace() || topic.IsNullOrWhiteSpace() || data.IsNullOrWhiteSpace()) { - var distributedEventBus = HttpContext.RequestServices.GetRequiredService(); - var eventData = daprSerializer.Deserialize(jsonElement.GetRawText(), distributedEventBus.GetEventType(request.Topic)); - await distributedEventBus.TriggerHandlersAsync(distributedEventBus.GetEventType(request.Topic), eventData); - return Ok(); + Logger.LogError("Invalid Dapr event request."); + return BadRequest(); } - Logger.LogError("Invalid Dapr event request."); - return BadRequest(); - } - - private static readonly ConcurrentDictionary JsonSerializerOptionsCache = new ConcurrentDictionary(); - - protected virtual JsonSerializerOptions CreateJsonSerializerOptions(IDaprSerializer daprSerializer) - { - return JsonSerializerOptionsCache.GetOrAdd(nameof(AbpAspNetCoreMvcDaprEventsController), _ => - { - var settings = new JsonSerializerOptions(JsonSerializerDefaults.Web) - { - PropertyNamingPolicy = new AbpDaprSubscriptionRequestJsonNamingPolicy() - }; - settings.Converters.Add(new AbpDaprSubscriptionRequestConverterFactory(daprSerializer)); - return settings; - }); + var distributedEventBus = HttpContext.RequestServices.GetRequiredService(); + var eventData = daprSerializer.Deserialize(data, distributedEventBus.GetEventType(topic)); + await distributedEventBus.TriggerHandlersAsync(distributedEventBus.GetEventType(topic), eventData); + return Ok(); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverter.cs deleted file mode 100644 index b0a4f72b12..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverter.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.Json; -using System.Text.Json.Serialization; -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; -using Volo.Abp.Dapr; - -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; - -public class AbpDaprSubscriptionRequestConverter : JsonConverter> - where T : class -{ - private JsonSerializerOptions _readJsonSerializerOptions; - - private readonly IDaprSerializer _daprSerializer; - - public AbpDaprSubscriptionRequestConverter(IDaprSerializer daprSerializer) - { - _daprSerializer = daprSerializer; - } - - public override AbpDaprSubscriptionRequest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - _readJsonSerializerOptions ??= CreateJsonSerializerOptions(options); - - var rootElement = JsonDocument.ParseValue(ref reader).RootElement; - var obj = JsonSerializer.Deserialize>(rootElement.GetRawText(), _readJsonSerializerOptions); - obj.Data = _daprSerializer.Deserialize(rootElement.GetProperty("data").GetRawText(), typeof(T)).As(); - return obj; - } - - public override void Write(Utf8JsonWriter writer, AbpDaprSubscriptionRequest value, JsonSerializerOptions options) - { - throw new NotSupportedException(); - } - - private JsonSerializerOptions CreateJsonSerializerOptions(JsonSerializerOptions options) - { - var newOptions = new JsonSerializerOptions(options); - newOptions.Converters.RemoveAll(x => x == this || x.GetType() == typeof(AbpDaprSubscriptionRequestConverterFactory)); - newOptions.PropertyNamingPolicy = new AbpDaprSubscriptionRequestJsonNamingPolicy(); - return newOptions; - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverterFactory.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverterFactory.cs deleted file mode 100644 index ec809c23d2..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestConverterFactory.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Serialization; -using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; -using Volo.Abp.Dapr; - -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; - -public class AbpDaprSubscriptionRequestConverterFactory : JsonConverterFactory -{ - private readonly IDaprSerializer _daprSerializer; - - public AbpDaprSubscriptionRequestConverterFactory(IDaprSerializer daprSerializer) - { - _daprSerializer = daprSerializer; - } - - public override bool CanConvert(Type typeToConvert) - { - return typeToConvert.GetGenericTypeDefinition() == typeof(AbpDaprSubscriptionRequest<>); - } - - public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) - { - return (JsonConverter)Activator.CreateInstance( - typeof(AbpDaprSubscriptionRequestConverter<>).MakeGenericType(typeToConvert.GetGenericArguments()[0]), - BindingFlags.Instance | BindingFlags.Public, - binder: null, - new object[] { _daprSerializer }, - culture: null)!; - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestJsonNamingPolicy.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestJsonNamingPolicy.cs deleted file mode 100644 index 89437f5fa3..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Json/AbpDaprSubscriptionRequestJsonNamingPolicy.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Text.Json; - -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Json; - -public class AbpDaprSubscriptionRequestJsonNamingPolicy : JsonNamingPolicy -{ - public override string ConvertName(string name) - { - return name.ToLower(); - } -} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpDaprSubscriptionRequest.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpDaprSubscriptionRequest.cs deleted file mode 100644 index ccf3724579..0000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpDaprSubscriptionRequest.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models; - -public class AbpDaprSubscriptionRequest - where T : class -{ - public string PubSubName { get; set; } - - public string Topic { get; set; } - - public T Data { get; set; } -} From a09dbf1318067e8278ae9d516562b3c6e4fe04b7 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 7 Nov 2022 15:38:53 +0800 Subject: [PATCH 6/9] Update Dapr document. --- docs/en/Dapr/Index.md | 30 ++++++++++++++++++++++++------ docs/zh-Hans/Dapr/Index.md | 32 +++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/docs/en/Dapr/Index.md b/docs/en/Dapr/Index.md index 5904b85508..060b31aac3 100644 --- a/docs/en/Dapr/Index.md +++ b/docs/en/Dapr/Index.md @@ -62,6 +62,27 @@ Alternatively, you can configure the options in the `Dapr` section of your `apps ### Injecting DaprClient +ABP registers the `DaprClient` class to the [dependency injection](../Dependency-Injection.md) system. So, you can inject and use it whenever you need: + +````csharp +public class MyService : ITransientDependency +{ + private readonly DaprClient _daprClient; + + public MyService(DaprClient daprClient) + { + _daprClient = daprClient; + } + + public async Task DoItAsync() + { + // TODO: Use the injected _daprClient object + } +} +```` + +Injecting `DaprClient` is the recommended way of using it in your application code. When you inject it, the `IAbpDaprClientFactory` service is used to create it, which is explained in the next section. + ### IAbpDaprClientFactory `IAbpDaprClientFactory` can be used to create `DaprClient` or `HttpClient` objects to perform operations on Dapr. It uses `AbpDaprOptions`, so you can configure the settings in a central place. @@ -249,18 +270,15 @@ In addition to ABP's standard distributed event bus system, you can also use Dap ````csharp public class MyService : ITransientDependency { - private readonly IAbpDaprClientFactory _daprClientFactory; + private readonly DaprClient _daprClient; - public MyService(IAbpDaprClientFactory daprClientFactory) + public MyService(DaprClient daprClient) { - _daprClientFactory = daprClientFactory; + _daprClient = daprClient; } public async Task DoItAsync() { - // Create a DaprClient object with default options - DaprClient _daprClient = await _daprClientFactory.CreateAsync(); - await _daprClient.PublishEventAsync( "pubsub", // pubsub name "StockChanged", // topic name diff --git a/docs/zh-Hans/Dapr/Index.md b/docs/zh-Hans/Dapr/Index.md index c4306f2c9f..64a9451737 100644 --- a/docs/zh-Hans/Dapr/Index.md +++ b/docs/zh-Hans/Dapr/Index.md @@ -62,6 +62,27 @@ Configure(options => ### 注入DaprClient +ABP 将 `DaprClient` 类注册到 [依赖注入](../Dependency-Injection.md) 系统中.因此,你可以在需要时注入并使用它: + +````csharp +public class MyService : ITransientDependency +{ + private readonly DaprClient _daprClient; + + public MyService(DaprClient daprClient) + { + _daprClient = daprClient; + } + + public async Task DoItAsync() + { + // TODO: Use the injected _daprClient object + } +} +```` + +注入 `DaprClient` 是在应用程序代码中使用它的推荐方法.当你注入它时,将使用 `IAbpDaprClientFactory` 服务创建它,这会在下一节中将进行说明. + ### IAbpDaprClientFactory `IAbpDaprClientFactory` 可用于创建 `DaprClient` 或 `HttpClient` 对象来执行对 Dapr 的操作.它使用 `AbpDaprOptions`,因此你可以配置设置. @@ -249,19 +270,16 @@ public class MyHandler : ````csharp public class MyService : ITransientDependency { - private readonly IAbpDaprClientFactory _daprClientFactory; + private readonly DaprClient _daprClient; - public MyService(IAbpDaprClientFactory daprClientFactory) + public MyService(DaprClient daprClient) { - _daprClientFactory = daprClientFactory; + _daprClient = daprClient; } public async Task DoItAsync() { - // Create a DaprClient object with default options - DaprClient daprClient = await _daprClientFactory.CreateAsync(); - - await daprClient.PublishEventAsync( + await _daprClient.PublishEventAsync( "pubsub", // pubsub name "StockChanged", // topic name new StockCountChangedEto // event data From a7c9240616bcd12259f53fae8b7894aa01b8564c Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Mon, 7 Nov 2022 10:41:24 +0300 Subject: [PATCH 7/9] add new issue templates --- .github/ISSUE_TEMPLATE/01_bug_report.yml | 148 ++++++++++++++++++ .github/ISSUE_TEMPLATE/02_feature_request.yml | 34 ++++ .github/ISSUE_TEMPLATE/03_article_request.yml | 20 +++ .../ISSUE_TEMPLATE/04_performance_issue.md | 49 ++++++ .../05_blank_issue.md} | 9 ++ .github/ISSUE_TEMPLATE/config.yml | 8 + .../ISSUE_TEMPLATES/community-post-request.md | 3 - .github/ISSUE_TEMPLATES/feature.md | 1 - 8 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/01_bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/02_feature_request.yml create mode 100644 .github/ISSUE_TEMPLATE/03_article_request.yml create mode 100644 .github/ISSUE_TEMPLATE/04_performance_issue.md rename .github/{ISSUE_TEMPLATE => ISSUE_TEMPLATE/05_blank_issue.md} (87%) create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATES/community-post-request.md delete mode 100644 .github/ISSUE_TEMPLATES/feature.md diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml new file mode 100644 index 0000000000..a2b33b7637 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/01_bug_report.yml @@ -0,0 +1,148 @@ +name: 🐞 Bug Report +description: Create a report to help us improve +labels: [bug] +body: + - type: markdown + attributes: + value: | + We welcome bug reports! This template will help us gather the information we need to start the triage process. + + Please keep in mind that the GitHub issue tracker is not intended as a general support forum, but for reporting **non-security** bugs and feature requests. + If you believe you have an issue that affects the SECURITY of the platform, please do NOT create an issue and instead email your issue details to info@abp.io. + For other types of questions, consider using [StackOverflow](https://stackoverflow.com/questions/tagged/abp). + - type: checkboxes + id: searched + attributes: + label: Is there an existing issue for this? + description: Please search to see if an issue already exists for the bug you encountered ([abp/issues](https://github.com/abpframework/abp/issues)). + options: + - label: I have searched the existing issues + required: true + - type: textarea + id: background + attributes: + label: Description + description: Please share a clear and concise description of the problem. + placeholder: Description + validations: + required: true + - type: textarea + id: repro-steps + attributes: + label: Reproduction Steps + description: | + Please include minimal steps to reproduce the problem if possible. E.g.: the smallest possible code snippet; or a small project, with steps to run it. If possible include text as text rather than screenshots (so it shows up in searches). + placeholder: Minimal Reproduction + validations: + required: false + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: | + Provide a description of the expected behavior. + placeholder: Expected behavior + validations: + required: false + - type: textarea + id: actual-behavior + attributes: + label: Actual behavior + description: | + Provide a description of the actual behavior observed. If applicable please include any error messages, exception stacktraces or memory dumps. + placeholder: Actual behavior + validations: + required: false + - type: textarea + id: regression + attributes: + label: Regression? + description: | + Did this work in a previous build or release of ABP framework? If you can try a previous release or build to find out, that can help us narrow down the problem. If you don't know, that's OK. + placeholder: Regression? + validations: + required: false + - type: textarea + id: known-workarounds + attributes: + label: Known Workarounds + description: | + Please provide a description of any known workarounds. + placeholder: Known Workarounds + validations: + required: false + - type: markdown + attributes: + value: | + ## Configuration + Please provide more information on your ABP configuration. + - type: input + id: version + attributes: + label: Version + description: Which version of ABP is the code running on? + placeholder: Version + validations: + required: true + - type: dropdown + id: user-interface + attributes: + label: User Interface + description: Which user interface of ABP is related to the problem? + options: + - Common (Default) + - MVC + - Angular + - Blazor + - Blazor Server + - React Native + - MAUI + validations: + required: true + - type: dropdown + id: database-provider + attributes: + label: Database Provider + description: Which database provider of ABP is used? + options: + - EF Core (Default) + - MongoDB + - None/Others + validations: + required: true + - type: dropdown + id: structure + attributes: + label: Tiered or separate authentication server + description: Which structure of ABP is specified? + options: + - None (Default) + - Tiered + - Separate Auth Server + validations: + required: true + - type: dropdown + id: Operation-System + attributes: + label: Operation System + description: What is the operation system of the server? + options: + - Windows (Default) + - Linux + - macOS + - Others + validations: + required: true + - type: markdown + attributes: + value: | + --- + - type: textarea + id: other-info + attributes: + label: Other information + description: | + If you have an idea where the problem might lie, let us know that here. Please include any pointers to code, relevant changes, or related issues you know of. + placeholder: Other information + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/02_feature_request.yml b/.github/ISSUE_TEMPLATE/02_feature_request.yml new file mode 100644 index 0000000000..21189e3a30 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02_feature_request.yml @@ -0,0 +1,34 @@ +name: 💡 Feature request +description: Suggest an idea for this project +labels: [feature] +body: +- type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please search to see if an issue already exists for the feature you are requesting. (https://github.com/abpframework/abp/issues). + options: + - label: I have searched the existing issues + required: true +- type: textarea + attributes: + label: Is your feature request related to a problem? Please describe the problem. + description: A clear and concise description of what the problem is. + placeholder: I am trying to do [...] but [...] + validations: + required: false +- type: textarea + attributes: + label: Describe the solution you'd like + description: | + A clear and concise description of what you want to happen. Include any alternative solutions you've considered. + placeholder: I would like to see [...] + validations: + required: true +- type: textarea + attributes: + label: Additional context + description: | + Add any other context or screenshots about the feature request here. + placeholder: Add any other context or screenshots about the feature request here. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/03_article_request.yml b/.github/ISSUE_TEMPLATE/03_article_request.yml new file mode 100644 index 0000000000..34082596c5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/03_article_request.yml @@ -0,0 +1,20 @@ +name: 💎 Article request +description: Article suggestion you want to be published on community.abp.io +labels: [community-article-request] +body: + - type: checkboxes + id: searched + attributes: + label: Is there an existing article or article request for this? + description: Please search to see if there is an article or article request related to your article request ([community.abp.io](https://community.abp.io/posts), [abp/issues](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+label%3Acommunity-article-request)) + options: + - label: I have searched the existing resources + required: true + - type: textarea + attributes: + label: Describe the article you'd like + description: | + Please describe the article you'd like to be published on community.abp.io. + If you have any reference article, please share it here. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/04_performance_issue.md b/.github/ISSUE_TEMPLATE/04_performance_issue.md new file mode 100644 index 0000000000..fb3d724f92 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/04_performance_issue.md @@ -0,0 +1,49 @@ +--- +name: Performance issue +about: Report a performance problem or regression +title: '' +labels: 'problem' +assignees: '' + +--- + + + +### Description + + + +### Configuration + + + +### Regression? + + + +### Data + + + +### Analysis + + diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE/05_blank_issue.md similarity index 87% rename from .github/ISSUE_TEMPLATE rename to .github/ISSUE_TEMPLATE/05_blank_issue.md index 414985237d..35138a6eed 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE/05_blank_issue.md @@ -1,3 +1,12 @@ +--- +name: Blank issue +about: Something that doesn't fit the other categories +title: '' +labels: '' +assignees: '' + +--- + ### Documentation Please check the official documentation before asking questions: https://docs.abp.io diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..8da2082360 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: Issue with ABP Commercial + url: https://support.abp.io/QA/Questions + about: Please open issues relating to ABP Commercial in support.abp.io. + - name: Ask a question (community support) + url: https://stackoverflow.com/questions/tagged/abp + about: Ask a question that will be answered by the ABP community diff --git a/.github/ISSUE_TEMPLATES/community-post-request.md b/.github/ISSUE_TEMPLATES/community-post-request.md deleted file mode 100644 index 1559e50a6c..0000000000 --- a/.github/ISSUE_TEMPLATES/community-post-request.md +++ /dev/null @@ -1,3 +0,0 @@ -Please explain the content (an article or a video tutorial) that you would like to see on the ABP Community website, https://community.abp.io. - -Before creating your own request, please check existing requests: https://github.com/abpframework/abp/labels/community-article-request \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATES/feature.md b/.github/ISSUE_TEMPLATES/feature.md deleted file mode 100644 index 3cc5678c46..0000000000 --- a/.github/ISSUE_TEMPLATES/feature.md +++ /dev/null @@ -1 +0,0 @@ -Please describe the feature need! \ No newline at end of file From 7953b952b1a90552f1b47070b28b83d68e809aaf Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Mon, 7 Nov 2022 11:05:18 +0300 Subject: [PATCH 8/9] Update 05_blank_issue.md --- .github/ISSUE_TEMPLATE/05_blank_issue.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/05_blank_issue.md b/.github/ISSUE_TEMPLATE/05_blank_issue.md index 35138a6eed..af0181fd66 100644 --- a/.github/ISSUE_TEMPLATE/05_blank_issue.md +++ b/.github/ISSUE_TEMPLATE/05_blank_issue.md @@ -13,9 +13,9 @@ Please check the official documentation before asking questions: https://docs.ab ### GitHub Issues -GitHub issues are for bug reports, feature requests and other discussions about the framework. +GitHub issues are for bug reports, feature requests, and other discussions about the framework. -If you're creating a bug/problem report, please include followings: +If you're creating a bug/problem report, please include the followings: * Your **ABP Framework version**. * Your **User Interface** type (Angular/MVC/React... etc.) if the issue is related to a specific UI @@ -27,7 +27,7 @@ Please **write in English**. ### Stack Overflow -Please use Stack Overflow for your questions about using the framework, templates and samples: +Please use Stack Overflow for your questions about using the framework, templates, and samples: https://stackoverflow.com/questions/tagged/abp From b7a616135eca96943e5be4f2c2782a5519e3cc9f Mon Sep 17 00:00:00 2001 From: Engincan VESKE Date: Mon, 7 Nov 2022 15:03:37 +0300 Subject: [PATCH 9/9] add new localizations --- .../Www/Localization/Resources/en.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json index faba7ab94e..74fec641a4 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json @@ -393,6 +393,18 @@ "BasicThemeInfo": "Minimalist UI theme with plain Bootstrap colors and styles. Ideal if you will build your own UI theme.", "SeeDocumentation": "See documentation.", "SeeFullScreen": "🖼️ See the screenshot", - "BuildingMicroserviceSolutionsShortDescription": "This book is a reference guide for developing and managing microservice-based applications using the ABP Framework." + "BuildingMicroserviceSolutionsShortDescription": "This book is a reference guide for developing and managing microservice-based applications using the ABP Framework.", + "InstallAbpCliMessage": "Install the ABP CLI in a command line terminal, if you haven't installed it before:", + "Terminal": "Terminal", + "Copy": "Copy", + "RunTheFollowingCommand": "Run the following command in a command line terminal:", + "ChangeSolutionOptionsBelow": "You can change the solution options below.", + "MultiLayerApplication": "Multi-layer
Application", + "MultiLayerApplicationExplanation1": "Creates a fully layered solution based on Domain Driven Design practices.", + "MultiLayerApplicationExplanation2": "Recommended for long-term projects that need a maintainable and extensible codebase.", + "SingleLayerApplication": "Single-layer
Application", + "SingleLayerApplicationExplanation1": "Creates a single-layer web application. ", + "SingleLayerApplicationExplanation2": "Recommended for building an application with a simpler and easy to understand architecture.", + "ApplicationModule": "Application
Module" } }