Browse Source

Merge branch 'dev' into saas-tenant-admin-password-12067

pull/14580/head
malik masis 3 years ago
parent
commit
3c1db07fcd
  1. 148
      .github/ISSUE_TEMPLATE/01_bug_report.yml
  2. 34
      .github/ISSUE_TEMPLATE/02_feature_request.yml
  3. 20
      .github/ISSUE_TEMPLATE/03_article_request.yml
  4. 49
      .github/ISSUE_TEMPLATE/04_performance_issue.md
  5. 15
      .github/ISSUE_TEMPLATE/05_blank_issue.md
  6. 8
      .github/ISSUE_TEMPLATE/config.yml
  7. 3
      .github/ISSUE_TEMPLATES/community-post-request.md
  8. 1
      .github/ISSUE_TEMPLATES/feature.md
  9. 14
      abp_io/AbpIoLocalization/AbpIoLocalization/Www/Localization/Resources/en.json
  10. 8
      docs/en/Dapr/Index.md
  11. 8
      docs/zh-Hans/Dapr/Index.md
  12. 296
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/DaprAspNetCore/AbpDaprEndpointRouteBuilderExtensions.cs
  13. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.csproj
  14. 61
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs
  15. 11
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusOptions.cs
  16. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubConsts.cs
  17. 63
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProvider.cs
  18. 16
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProviderContributorContext.cs
  19. 38
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs
  20. 38
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprPubSubController.cs
  21. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/IAbpAspNetCoreMvcDaprPubSubProviderContributor.cs
  22. 10
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionDefinition.cs
  23. 8
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionRequest.cs
  24. 11
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprPubSubJsonNamingPolicy.cs
  25. 25
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter.cs
  26. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo.Abp.AspNetCore.Mvc.Dapr.csproj
  27. 21
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprAppApiTokenValidator.cs
  28. 11
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs
  29. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs
  30. 4
      framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj
  31. 16
      framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs
  32. 5
      framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs
  33. 8
      framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs
  34. 12
      framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs
  35. 8
      framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs
  36. 10
      framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprSerializer.cs
  37. 18
      framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/Utf8JsonDaprSerializer.cs
  38. 6
      framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj
  39. 10
      framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/AbpDistributedLockDaprOptions.cs
  40. 17
      framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLock.cs
  41. 9
      framework/src/Volo.Abp.DistributedLocking.Dapr/Volo/Abp/DistributedLocking/Dapr/DaprAbpDistributedLockHandle.cs
  42. 4
      framework/src/Volo.Abp.EventBus.Dapr/Volo.Abp.EventBus.Dapr.csproj
  43. 12
      framework/src/Volo.Abp.EventBus.Dapr/Volo/Abp/EventBus/Dapr/DaprDistributedEventBus.cs
  44. 4
      framework/src/Volo.Abp.Http.Client.Dapr/Volo.Abp.Http.Client.Dapr.csproj
  45. 5
      framework/src/Volo.Abp.Http.Client.Dapr/Volo/Abp/Http/Client/Dapr/AbpInvocationHandler.cs

148
.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

34
.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

20
.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

49
.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: ''
---
<!--This is just a template - feel free to delete any and all of it and replace as appropriate.-->
### Description
<!--
* Please share a clear and concise description of the performance problem.
* Include minimal steps to reproduce the problem if possible. E.g.: the smallest possible code snippet; or a small repo to clone, with steps to run it.
-->
### Configuration
<!--
(If you are posting Benchmark.NET results, this info will be included.)
* Which version of .NET is the code running on?
* What OS version, and what distro if applicable?
* What is the architecture (x64, x86, ARM, ARM64)?
* If relevant, what are the specs of the machine?
-->
### Regression?
<!--
* 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.
-->
### Data
<!--
* Please include any benchmark results, images of graphs, timings or measurements, or callstacks that are relevant.
* If possible please include text as text rather than images (so it shows up in searches).
* If applicable please include before and after measurements.
-->
### Analysis
<!--
* 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.
* If you don't know, you can delete this section.
-->

15
.github/ISSUE_TEMPLATE → .github/ISSUE_TEMPLATE/05_blank_issue.md

@ -1,12 +1,21 @@
---
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
### 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
@ -18,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

8
.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

3
.github/ISSUE_TEMPLATES/community-post-request.md

@ -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

1
.github/ISSUE_TEMPLATES/feature.md

@ -1 +0,0 @@
Please describe the feature need!

14
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 <a href='{0}' target='_blank'>documentation</a>.",
"SeeFullScreen": "<a href='{0}' target='_blank'>🖼️ See the screenshot</a>",
"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 <br>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 <br>Application",
"SingleLayerApplicationExplanation1": "Creates a single-layer web application. ",
"SingleLayerApplicationExplanation2": "Recommended for building an application with a simpler and easy to understand architecture.",
"ApplicationModule": "Application <br>Module"
}
}

8
docs/en/Dapr/Index.md

@ -209,7 +209,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
@ -299,8 +299,7 @@ public class MyController : AbpController
{
[HttpPost("/stock-changed")]
[Topic("pubsub", "StockChanged")]
public async Task<IActionResult> TestRouteAsync(
[FromBody] StockCountChangedEto model)
public async Task<IActionResult> TestRouteAsync([FromBody] StockCountChangedEto model)
{
HttpContext.ValidateDaprAppApiToken();
@ -430,8 +429,7 @@ public class MyController : AbpController
{
[HttpPost("/stock-changed")]
[Topic("pubsub", "StockChanged")]
public async Task<IActionResult> TestRouteAsync(
[FromBody] StockCountChangedEto model)
public async Task<IActionResult> TestRouteAsync([FromBody] StockCountChangedEto model)
{
// Validate the App API token!
HttpContext.ValidateDaprAppApiToken();

8
docs/zh-Hans/Dapr/Index.md

@ -209,7 +209,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()`中间件.
### 用法
@ -299,8 +299,7 @@ public class MyController : AbpController
{
[HttpPost("/stock-changed")]
[Topic("pubsub", "StockChanged")]
public async Task<IActionResult> TestRouteAsync(
[FromBody] StockCountChangedEto model)
public async Task<IActionResult> TestRouteAsync([FromBody] StockCountChangedEto model)
{
HttpContext.ValidateDaprAppApiToken();
@ -430,8 +429,7 @@ public class MyController : AbpController
{
[HttpPost("/stock-changed")]
[Topic("pubsub", "StockChanged")]
public async Task<IActionResult> TestRouteAsync(
[FromBody] StockCountChangedEto model)
public async Task<IActionResult> TestRouteAsync([FromBody] StockCountChangedEto model)
{
// Validate the App API token!
HttpContext.ValidateDaprAppApiToken();

296
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
{
/// <summary>
/// This class defines configurations for the subscribe endpoint.
/// </summary>
public class AbpSubscribeOptions
{
/// <summary>
/// Gets or Sets a value which indicates whether to enable or disable processing raw messages.
/// </summary>
public bool EnableRawPayload { get; set; }
/// <summary>
/// An optional delegate used to configure the subscriptions.
/// </summary>
public Func<List<AbpSubscription>, Task> SubscriptionsCallback { get; set; }
}
/// <summary>
/// This class defines subscribe endpoint response
/// </summary>
public class AbpSubscription
{
/// <summary>
/// Gets or sets the topic name.
/// </summary>
public string Topic { get; set; }
/// <summary>
/// Gets or sets the pubsub name
/// </summary>
public string PubsubName { get; set; }
/// <summary>
/// Gets or sets the route
/// </summary>
public string Route { get; set; }
/// <summary>
/// Gets or sets the routes
/// </summary>
public AbpRoutes Routes { get; set; }
/// <summary>
/// Gets or sets the metadata.
/// </summary>
public AbpMetadata Metadata { get; set; }
/// <summary>
/// Gets or sets the deadletter topic.
/// </summary>
public string DeadLetterTopic { get; set; }
}
/// <summary>
/// This class defines the metadata for subscribe endpoint.
/// </summary>
public class AbpMetadata : Dictionary<string, string>
{
/// <summary>
/// Initializes a new instance of the Metadata class.
/// </summary>
public AbpMetadata() { }
/// <summary>
/// Initializes a new instance of the Metadata class.
/// </summary>
/// <param name="dictionary"></param>
public AbpMetadata(IDictionary<string, string> dictionary) : base(dictionary) { }
/// <summary>
/// RawPayload key
/// </summary>
internal const string RawPayload = "rawPayload";
}
/// <summary>
/// This class defines the routes for subscribe endpoint.
/// </summary>
public class AbpRoutes
{
/// <summary>
/// Gets or sets the default route
/// </summary>
public string Default { get; set; }
/// <summary>
/// Gets or sets the routing rules
/// </summary>
public List<AbpRule> Rules { get; set; }
}
/// <summary>
/// This class defines the rule for subscribe endpoint.
/// </summary>
public class AbpRule
{
/// <summary>
/// Gets or sets the CEL expression to match this route.
/// </summary>
public string Match { get; set; }
/// <summary>
/// Gets or sets the path of the route.
/// </summary>
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;
/// <summary>
/// Contains extension methods for <see cref="IEndpointRouteBuilder" />.
/// </summary>
public static class AbpDaprEndpointRouteBuilderExtensions
{
/// <summary>
/// Maps an endpoint that will respond to requests to <c>/dapr/subscribe</c> from the
/// Dapr runtime.
/// </summary>
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder" />.</param>
/// <returns>The <see cref="IEndpointConventionBuilder" />.</returns>
public static IEndpointConventionBuilder MapAbpSubscribeHandler(this IEndpointRouteBuilder endpoints)
{
return CreateSubscribeEndPoint(endpoints);
}
/// <summary>
/// Maps an endpoint that will respond to requests to <c>/dapr/subscribe</c> from the
/// Dapr runtime.
/// </summary>
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder" />.</param>
/// <param name="options">Configuration options</param>
/// <returns>The <see cref="IEndpointConventionBuilder" />.</returns>
/// <seealso cref="MapAbpSubscribeHandler(IEndpointRouteBuilder)"/>
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<ILoggerFactory>().CreateLogger("DaprTopicSubscription");
var dataSource = context.RequestServices.GetRequiredService<EndpointDataSource>();
var subscriptions = dataSource.Endpoints
.OfType<RouteEndpoint>()
.Where(e => e.Metadata.GetOrderedMetadata<ITopicMetadata>().Any(t => t.Name != null)) // only endpoints which have TopicAttribute with not null Name.
.SelectMany(e =>
{
var topicMetadata = e.Metadata.GetOrderedMetadata<ITopicMetadata>();
var originalTopicMetadata = e.Metadata.GetOrderedMetadata<IOriginalTopicMetadata>();
var subs = new List<(string PubsubName, string Name, string DeadLetterTopic, bool? EnableRawPayload, string Match, int Priority, Dictionary<string, string[]> 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<RoutePatternLiteralPart>()
.Select(part => part.Content))));
}
}
}

2
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.csproj

@ -5,8 +5,6 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>

61
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusModule.cs

@ -1,7 +1,14 @@
using Microsoft.AspNetCore.Http.Json;
using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.SystemTextJson;
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 +21,50 @@ public class AbpAspNetCoreMvcDaprEventBusModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// TODO: Add NewtonsoftJson json converter.
var subscribeOptions = context.Services.ExecutePreConfiguredActions<AbpSubscribeOptions>();
Configure<JsonOptions>(options =>
Configure<AbpEndpointRouterOptions>(options =>
{
options.SerializerOptions.Converters.Add(new AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter());
});
options.EndpointConfigureActions.Add(endpointContext =>
{
var rootServiceProvider = endpointContext.ScopeServiceProvider.GetRequiredService<IRootServiceProvider>();
subscribeOptions.SubscriptionsCallback = subscriptions =>
{
var daprEventBusOptions = rootServiceProvider.GetRequiredService<IOptions<AbpDaprEventBusOptions>>().Value;
foreach (var handler in rootServiceProvider.GetRequiredService<IOptions<AbpDistributedEventBusOptions>>().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);
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.JsonSerializerOptions.Converters.Add(new AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter());
if (subscriptions.Any(x => x.PubsubName == daprEventBusOptions.PubSubName && x.Topic == eventName))
{
// Controllers with a [Topic] attribute can replace built-in event handlers.
continue;
}
var subscription = new AbpSubscription
{
PubsubName = daprEventBusOptions.PubSubName,
Topic = eventName,
Route = AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl,
Metadata = new AbpMetadata
{
{
AbpMetadata.RawPayload, "true"
}
}
};
subscriptions.Add(subscription);
}
}
return Task.CompletedTask;
};
endpointContext.Endpoints.MapAbpSubscribeHandler(subscribeOptions);
});
});
}
}

11
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprEventBusOptions.cs

@ -1,11 +0,0 @@
namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus;
public class AbpAspNetCoreMvcDaprEventBusOptions
{
public List<IAbpAspNetCoreMvcDaprPubSubProviderContributor> Contributors { get; }
public AbpAspNetCoreMvcDaprEventBusOptions()
{
Contributors = new List<IAbpAspNetCoreMvcDaprPubSubProviderContributor>();
}
}

2
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";
}

63
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProvider.cs

@ -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<AbpAspNetCoreMvcDaprEventBusOptions> aspNetCoreDaprEventBusOptions,
IOptions<AbpDaprEventBusOptions> daprEventBusOptions,
IOptions<AbpDistributedEventBusOptions> distributedEventBusOptions)
{
ServiceProvider = serviceProvider;
AspNetCoreMvcDaprEventBusOptions = aspNetCoreDaprEventBusOptions.Value;
DaprEventBusOptions = daprEventBusOptions.Value;
DistributedEventBusOptions = distributedEventBusOptions.Value;
}
public virtual async Task<List<AbpAspNetCoreMvcDaprSubscriptionDefinition>> GetSubscriptionsAsync()
{
var subscriptions = new List<AbpAspNetCoreMvcDaprSubscriptionDefinition>();
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;
}
}

16
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/AbpAspNetCoreMvcDaprPubSubProviderContributorContext.cs

@ -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<AbpAspNetCoreMvcDaprSubscriptionDefinition> Subscriptions { get; }
public AbpAspNetCoreMvcDaprPubSubProviderContributorContext(IServiceProvider serviceProvider, List<AbpAspNetCoreMvcDaprSubscriptionDefinition> daprSubscriptionModels)
{
ServiceProvider = serviceProvider;
Subscriptions = daprSubscriptionModels;
}
}

38
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprEventsController.cs

@ -0,0 +1,38 @@
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.Dapr;
using Volo.Abp.EventBus.Dapr;
namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Controllers;
[Area("abp")]
[RemoteService(Name = "abp")]
public class AbpAspNetCoreMvcDaprEventsController : AbpController
{
[HttpPost(AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl)]
public virtual async Task<IActionResult> EventAsync()
{
HttpContext.ValidateDaprAppApiToken();
var daprSerializer = HttpContext.RequestServices.GetRequiredService<IDaprSerializer>();
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())
{
Logger.LogError("Invalid Dapr event request.");
return BadRequest();
}
var distributedEventBus = HttpContext.RequestServices.GetRequiredService<DaprDistributedEventBus>();
var eventData = daprSerializer.Deserialize(data, distributedEventBus.GetEventType(topic));
await distributedEventBus.TriggerHandlersAsync(distributedEventBus.GetEventType(topic), eventData);
return Ok();
}
}

38
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Controllers/AbpAspNetCoreMvcDaprPubSubController.cs

@ -1,38 +0,0 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models;
using Volo.Abp.Dapr;
using Volo.Abp.EventBus.Dapr;
namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Controllers;
[Area("abp")]
[RemoteService(Name = "abp")]
public class AbpAspNetCoreMvcDaprPubSubController : AbpController
{
[HttpGet(AbpAspNetCoreMvcDaprPubSubConsts.DaprSubscribeUrl)]
public virtual async Task<List<AbpAspNetCoreMvcDaprSubscriptionDefinition>> SubscribeAsync()
{
return await HttpContext.RequestServices.GetRequiredService<AbpAspNetCoreMvcDaprPubSubProvider>().GetSubscriptionsAsync();
}
[HttpPost(AbpAspNetCoreMvcDaprPubSubConsts.DaprEventCallbackUrl)]
public virtual async Task<IActionResult> EventsAsync()
{
this.HttpContext.ValidateDaprAppApiToken();
var bodyJsonDocument = await JsonDocument.ParseAsync(HttpContext.Request.Body);
var request = JsonSerializer.Deserialize<AbpAspNetCoreMvcDaprSubscriptionRequest>(bodyJsonDocument.RootElement.GetRawText(),
HttpContext.RequestServices.GetRequiredService<IOptions<JsonOptions>>().Value.JsonSerializerOptions);
var distributedEventBus = HttpContext.RequestServices.GetRequiredService<DaprDistributedEventBus>();
var daprSerializer = HttpContext.RequestServices.GetRequiredService<IDaprSerializer>();
var eventData = daprSerializer.Deserialize(bodyJsonDocument.RootElement.GetProperty("data").GetRawText(), distributedEventBus.GetEventType(request.Topic));
await distributedEventBus.TriggerHandlersAsync(distributedEventBus.GetEventType(request.Topic), eventData);
return Ok();
}
}

6
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/IAbpAspNetCoreMvcDaprPubSubProviderContributor.cs

@ -1,6 +0,0 @@
namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus;
public interface IAbpAspNetCoreMvcDaprPubSubProviderContributor
{
Task ContributeAsync(AbpAspNetCoreMvcDaprPubSubProviderContributorContext context);
}

10
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionDefinition.cs

@ -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; }
}

8
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/Models/AbpAspNetCoreMvcDaprSubscriptionRequest.cs

@ -1,8 +0,0 @@
namespace Volo.Abp.AspNetCore.Mvc.Dapr.EventBus.Models;
public class AbpAspNetCoreMvcDaprSubscriptionRequest
{
public string PubSubName { get; set; }
public string Topic { get; set; }
}

11
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprPubSubJsonNamingPolicy.cs

@ -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();
}
}

25
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus/Volo/Abp/AspNetCore/Mvc/Dapr/EventBus/SystemTextJson/AbpAspNetCoreMvcDaprSubscriptionDefinitionConverter.cs

@ -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<AbpAspNetCoreMvcDaprSubscriptionDefinition>
{
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);
}
}

4
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo.Abp.AspNetCore.Mvc.Dapr.csproj

@ -5,8 +5,6 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>
@ -16,7 +14,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dapr.AspNetCore" Version="1.8.0" />
<PackageReference Include="Dapr.AspNetCore" Version="1.9.0" />
</ItemGroup>
</Project>

21
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,13 +11,13 @@ 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()
{
var expectedAppApiToken = GetConfiguredAppApiTokenOrNull();
@ -24,7 +25,7 @@ public class DaprAppApiTokenValidator : IDaprAppApiTokenValidator, ISingletonDep
{
return;
}
var headerAppApiToken = GetDaprAppApiTokenOrNull();
if (headerAppApiToken.IsNullOrWhiteSpace())
{
@ -44,12 +45,12 @@ public class DaprAppApiTokenValidator : IDaprAppApiTokenValidator, ISingletonDep
{
return true;
}
var headerAppApiToken = GetDaprAppApiTokenOrNull();
return expectedAppApiToken == headerAppApiToken;
}
public virtual string? GetDaprAppApiTokenOrNull()
public virtual string GetDaprAppApiTokenOrNull()
{
string apiTokenHeader = HttpContext.Request.Headers["dapr-api-token"];
if (string.IsNullOrEmpty(apiTokenHeader) || apiTokenHeader.Length < 1)
@ -59,8 +60,8 @@ public class DaprAppApiTokenValidator : IDaprAppApiTokenValidator, ISingletonDep
return apiTokenHeader;
}
protected virtual string? GetConfiguredAppApiTokenOrNull()
protected virtual string GetConfiguredAppApiTokenOrNull()
{
return HttpContext
.RequestServices
@ -72,4 +73,4 @@ public class DaprAppApiTokenValidator : IDaprAppApiTokenValidator, ISingletonDep
{
return HttpContextAccessor.HttpContext ?? throw new AbpException("HttpContext is not available!");
}
}
}

11
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/DaprHttpContextExtensions.cs

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.Dapr;
@ -12,7 +13,7 @@ public static class DaprHttpContextExtensions
.GetRequiredService<IDaprAppApiTokenValidator>()
.CheckDaprAppApiToken();
}
public static bool IsValidDaprAppApiToken(this HttpContext httpContext)
{
return httpContext
@ -20,12 +21,12 @@ public static class DaprHttpContextExtensions
.GetRequiredService<IDaprAppApiTokenValidator>()
.IsValidDaprAppApiToken();
}
public static string? GetDaprAppApiTokenOrNull(HttpContext httpContext)
public static string GetDaprAppApiTokenOrNull(HttpContext httpContext)
{
return httpContext
.RequestServices
.GetRequiredService<IDaprAppApiTokenValidator>()
.GetDaprAppApiTokenOrNull();
}
}
}

6
framework/src/Volo.Abp.AspNetCore.Mvc.Dapr/Volo/Abp/AspNetCore/Mvc/Dapr/IDaprAppApiTokenValidator.cs

@ -3,6 +3,8 @@ namespace Volo.Abp.AspNetCore.Mvc.Dapr;
public interface IDaprAppApiTokenValidator
{
void CheckDaprAppApiToken();
bool IsValidDaprAppApiToken();
string? GetDaprAppApiTokenOrNull();
}
string GetDaprAppApiTokenOrNull();
}

4
framework/src/Volo.Abp.Dapr/Volo.Abp.Dapr.csproj

@ -5,8 +5,6 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>
@ -15,7 +13,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dapr.Client" Version="1.8.0" />
<PackageReference Include="Dapr.Client" Version="1.9.0" />
</ItemGroup>
</Project>

16
framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprClientFactory.cs

@ -1,4 +1,6 @@
using System.Text.Json;
using System;
using System.Net.Http;
using System.Text.Json;
using Dapr.Client;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -22,7 +24,7 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency
JsonSerializerOptions = CreateJsonSerializerOptions(systemTextJsonSerializerOptions.Value);
}
public virtual DaprClient Create(Action<DaprClientBuilder>? builderAction = null)
public virtual DaprClient Create(Action<DaprClientBuilder> builderAction = null)
{
var builder = new DaprClientBuilder()
.UseJsonSerializationOptions(JsonSerializerOptions);
@ -49,9 +51,9 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency
}
public virtual HttpClient CreateHttpClient(
string? appId = null,
string? daprEndpoint = null,
string? daprApiToken = null)
string appId = null,
string daprEndpoint = null,
string daprApiToken = null)
{
if(daprEndpoint.IsNullOrWhiteSpace() &&
!DaprOptions.HttpEndpoint.IsNullOrWhiteSpace())
@ -65,9 +67,9 @@ public class AbpDaprClientFactory : IAbpDaprClientFactory, ISingletonDependency
daprApiToken ?? DaprApiTokenProvider.GetDaprApiToken()
);
}
protected virtual JsonSerializerOptions CreateJsonSerializerOptions(AbpSystemTextJsonSerializerOptions systemTextJsonSerializerOptions)
{
return new JsonSerializerOptions(systemTextJsonSerializerOptions.JsonSerializerOptions);
}
}
}

5
framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/AbpDaprModule.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.Configuration;
using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Json;
@ -12,7 +13,7 @@ public class AbpDaprModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
ConfigureDaprOptions(configuration);
context.Services.TryAddSingleton(

8
framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/DaprApiTokenProvider.cs

@ -11,14 +11,14 @@ public class DaprApiTokenProvider : IDaprApiTokenProvider, ISingletonDependency
{
Options = options.Value;
}
public virtual string? GetDaprApiToken()
public virtual string GetDaprApiToken()
{
return Options.DaprApiToken;
}
public virtual string? GetAppApiToken()
public virtual string GetAppApiToken()
{
return Options.AppApiToken;
}
}
}

12
framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IAbpDaprClientFactory.cs

@ -1,14 +1,16 @@
using System;
using System.Net.Http;
using Dapr.Client;
namespace Volo.Abp.Dapr;
public interface IAbpDaprClientFactory
{
DaprClient Create(Action<DaprClientBuilder>? builderAction = null);
DaprClient Create(Action<DaprClientBuilder> builderAction = null);
HttpClient CreateHttpClient(
string? appId = null,
string? daprEndpoint = null,
string? daprApiToken = null
string appId = null,
string daprEndpoint = null,
string daprApiToken = null
);
}
}

8
framework/src/Volo.Abp.Dapr/Volo/Abp/Dapr/IDaprApiTokenProvider.cs

@ -2,7 +2,7 @@ namespace Volo.Abp.Dapr;
public interface IDaprApiTokenProvider
{
string? GetDaprApiToken();
string? GetAppApiToken();
}
string GetDaprApiToken();
string GetAppApiToken();
}

10
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
{
@ -6,11 +8,5 @@ public interface IDaprSerializer
object Deserialize(byte[] value, Type type);
T Deserialize<T>(byte[] value);
string SerializeToString(object obj);
object Deserialize(string value, Type type);
T Deserialize<T>(string value);
}

18
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;
@ -23,23 +24,8 @@ public class Utf8JsonDaprSerializer : IDaprSerializer, ITransientDependency
return _jsonSerializer.Deserialize(type, Encoding.UTF8.GetString(value));
}
public T Deserialize<T>(byte[] value)
{
return _jsonSerializer.Deserialize<T>(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<T>(string value)
{
return _jsonSerializer.Deserialize<T>(value);
}
}

6
framework/src/Volo.Abp.DistributedLocking.Dapr/Volo.Abp.DistributedLocking.Dapr.csproj

@ -2,11 +2,9 @@
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>
@ -14,5 +12,5 @@
<ProjectReference Include="..\Volo.Abp.Dapr\Volo.Abp.Dapr.csproj" />
<ProjectReference Include="..\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" />
</ItemGroup>
</Project>

10
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);
}
}
}

17
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<AbpDistributedLockDaprOptions> distributedLockDaprOptions,
@ -20,8 +23,8 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency
DistributedLockKeyNormalizer = distributedLockKeyNormalizer;
DistributedLockDaprOptions = distributedLockDaprOptions.Value;
}
public async Task<IAbpDistributedLockHandle?> TryAcquireAsync(
public async Task<IAbpDistributedLockHandle> TryAcquireAsync(
string name,
TimeSpan timeout = default,
CancellationToken cancellationToken = default)
@ -30,8 +33,8 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency
var daprClient = DaprClientFactory.Create();
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);
}
}
}

9
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();
}
}
}

4
framework/src/Volo.Abp.EventBus.Dapr/Volo.Abp.EventBus.Dapr.csproj

@ -2,11 +2,9 @@
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>

12
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<OutgoingEventInfo> outgoingEvents, OutboxConfig outboxConfig)
public override async Task PublishManyFromOutboxAsync(IEnumerable<OutgoingEventInfo> outgoingEvents, OutboxConfig outboxConfig)
{
var outgoingEventArray = outgoingEvents.ToArray();

4
framework/src/Volo.Abp.Http.Client.Dapr/Volo.Abp.Http.Client.Dapr.csproj

@ -2,11 +2,9 @@
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>

5
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;
}
}
}
}

Loading…
Cancel
Save