Browse Source

dispose response of HttpClient #6534

pull/6693/head
Alper Ebicoglu 6 years ago
parent
commit
0a47340528
  1. 1
      docs/en/CLI.md
  2. 28
      docs/en/UI/AspNetCore/Data-Tables.md
  3. 1
      docs/zh-Hans/CLI.md
  4. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
  5. 4
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs
  6. 2
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerAdapter.cs
  7. 25
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AsyncPeriodicBackgroundWorkerBase.cs
  8. 6
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/PeriodicBackgroundWorkerBase.cs
  9. 2
      framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs
  10. 22
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs
  11. 94
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs
  12. 12
      framework/src/Volo.Abp.Cli/Volo/Abp/Cli/Program.cs
  13. 51
      framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs
  14. 127
      framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AbpAsyncTimer.cs
  15. 2
      framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AbpTimer.cs
  16. 4
      framework/test/Volo.Abp.BlobStoring.Aws.Tests/Volo/Abp/BlobStoring/Aws/AbpBlobStoringAwsTestModule.cs
  17. 987
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20201208084431_Added_CommitCount.Designer.cs
  18. 24
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20201208084431_Added_CommitCount.cs
  19. 5
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/VoloDocsDbContextModelSnapshot.cs
  20. 2
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentContributorDto.cs
  21. 4
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/Document.cs
  22. 5
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentContributor.cs
  23. 13
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/DocumentAuthor.cs
  24. 31
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs
  25. 2
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  26. 7
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Tokens/TokenCleanupBackgroundWorker.cs

1
docs/en/CLI.md

@ -129,6 +129,7 @@ abp update [options]
* `--solution-path` or `-sp`: Specify the solution path. Use the current directory by default
* `--solution-name` or `-sn`: Specify the solution name. Search `*.sln` files in the directory by default.
* `--check-all`: Check the new version of each package separately. Default is `false`.
* `--version` or `-v`: Specifies the version to use for update. If not specified, latest version is used.
### add-package

28
docs/en/UI/AspNetCore/Data-Tables.md

@ -105,6 +105,32 @@ The `abp.libs.datatables.createAjax` method (used in the example above) adapts r
This works automatically, so most of the times you don't need to know how it works. See the [DTO document](../../Data-Transfer-Objects.md) if you want to learn more about `IPagedAndSortedResultRequest`, `IPagedResult` and other standard interfaces and base DTO classes those are used in client to server communication.
The `createAjax` also supports you to customize request parameters and handle the responses.
**Example:**
````csharp
var inputAction = function () {
return {
id: $('#Id').val(),
name: $('#Name').val(),
};
};
var responseCallback = function(result) {
// your custom code.
return {
recordsTotal: result.totalCount,
recordsFiltered: result.totalCount,
data: result.items
};
};
ajax: abp.libs.datatables.createAjax(acme.bookStore.books.book.getList, inputAction, responseCallback)
````
### Row Actions
`rowAction` is an option defined by the ABP Framework to the column definitions to show a drop down button to take actions for a row in the table.
@ -260,4 +286,4 @@ Assuming that the possible values for a column data is `f` and `m`, the `gender`
## Other Data Grids
You can use any library you like. For example, [see this article](https://community.abp.io/articles/using-devextreme-components-with-the-abp-framework-zb8z7yqv) to learn how to use DevExtreme Data Grid in your applications.
You can use any library you like. For example, [see this article](https://community.abp.io/articles/using-devextreme-components-with-the-abp-framework-zb8z7yqv) to learn how to use DevExtreme Data Grid in your applications.

1
docs/zh-Hans/CLI.md

@ -126,6 +126,7 @@ abp update [options]
* `--solution-path` 或 `-sp`: 指定解决方案路径/目录. 默认使用当前目录
* `--solution-name` 或 `-sn`: 指定解决方案名称. 默认在目录中搜索`*.sln`文件.
* `--check-all`: 分别检查每个包的新版本. 默认是 `false`.
* `--version` or `-v`: 指定用于升级的版本. 如果没有指定,则使用最新版本.
### add-package

15
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js

@ -325,7 +325,14 @@
* AJAX extension for datatables *
*************************************************************************/
(function () {
datatables.createAjax = function (serverMethod, inputAction) {
datatables.createAjax = function (serverMethod, inputAction, responseCallback) {
responseCallback = responseCallback || function(result) {
return {
recordsTotal: result.totalCount,
recordsFiltered: result.totalCount,
data: result.items
};
}
return function (requestData, callback, settings) {
var input = inputAction ? inputAction(requestData, settings) : {};
@ -359,11 +366,7 @@
if (callback) {
serverMethod(input).then(function (result) {
callback({
recordsTotal: result.totalCount,
recordsFiltered: result.totalCount,
data: result.items
});
callback(responseCallback(result));
});
}
};

4
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs

@ -17,7 +17,7 @@ namespace Volo.Abp.BackgroundJobs
protected AbpBackgroundJobWorkerOptions WorkerOptions { get; }
public BackgroundJobWorker(
AbpTimer timer,
AbpAsyncTimer timer,
IOptions<AbpBackgroundJobOptions> jobOptions,
IOptions<AbpBackgroundJobWorkerOptions> workerOptions,
IServiceScopeFactory serviceScopeFactory)
@ -113,4 +113,4 @@ namespace Volo.Abp.BackgroundJobs
return nextTryDate;
}
}
}
}

2
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerAdapter.cs

@ -34,7 +34,7 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
throw new ArgumentException($"{nameof(worker)} type is different from the generic type");
}
var timer = (AbpTimer) worker.GetType().GetProperty("Timer", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(worker);
var timer = (AbpAsyncTimer) worker.GetType().GetProperty("Timer", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(worker);
period = timer?.Period;
}
else

25
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AsyncPeriodicBackgroundWorkerBase.cs

@ -11,15 +11,15 @@ namespace Volo.Abp.BackgroundWorkers
public abstract class AsyncPeriodicBackgroundWorkerBase : BackgroundWorkerBase
{
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected AbpTimer Timer { get; }
protected AbpAsyncTimer Timer { get; }
protected AsyncPeriodicBackgroundWorkerBase(
AbpTimer timer,
AbpAsyncTimer timer,
IServiceScopeFactory serviceScopeFactory)
{
ServiceScopeFactory = serviceScopeFactory;
Timer = timer;
Timer.Elapsed += Timer_Elapsed;
Timer.Elapsed = Timer_Elapsed;
}
public async override Task StartAsync(CancellationToken cancellationToken = default)
@ -34,23 +34,24 @@ namespace Volo.Abp.BackgroundWorkers
await base.StopAsync(cancellationToken);
}
private void Timer_Elapsed(object sender, System.EventArgs e)
private async Task Timer_Elapsed(AbpAsyncTimer timer)
{
await DoWorkAsync();
}
private async Task DoWorkAsync()
{
using (var scope = ServiceScopeFactory.CreateScope())
{
try
{
AsyncHelper.RunSync(
() => DoWorkAsync(new PeriodicBackgroundWorkerContext(scope.ServiceProvider))
);
await DoWorkAsync(new PeriodicBackgroundWorkerContext(scope.ServiceProvider));
}
catch (Exception ex)
{
AsyncHelper.RunSync(
() => scope.ServiceProvider
.GetRequiredService<IExceptionNotifier>()
.NotifyAsync(new ExceptionNotificationContext(ex))
);
await scope.ServiceProvider
.GetRequiredService<IExceptionNotifier>()
.NotifyAsync(new ExceptionNotificationContext(ex));
Logger.LogException(ex);
}

6
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/PeriodicBackgroundWorkerBase.cs

@ -43,14 +43,12 @@ namespace Volo.Abp.BackgroundWorkers
{
try
{
DoWork(new PeriodicBackgroundWorkerContext(scope.ServiceProvider));
}
catch (Exception ex)
{
scope.ServiceProvider
.GetRequiredService<IExceptionNotifier>()
.NotifyAsync(new ExceptionNotificationContext(ex));
var exceptionNotifier = scope.ServiceProvider.GetRequiredService<IExceptionNotifier>();
AsyncHelper.RunSync(() => exceptionNotifier.NotifyAsync(new ExceptionNotificationContext(ex)));
Logger.LogException(ex);
}

2
framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs

@ -1029,7 +1029,7 @@ namespace Volo.Abp.Caching
protected virtual void HandleException(Exception ex)
{
AsyncHelper.RunSync(() => HandleExceptionAsync(ex));
_ = HandleExceptionAsync(ex);
}
protected virtual async Task HandleExceptionAsync(Exception ex)

22
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs

@ -34,24 +34,25 @@ namespace Volo.Abp.Cli.Commands
var directory = commandLineArgs.Options.GetOrNull(Options.SolutionPath.Short, Options.SolutionPath.Long) ??
Directory.GetCurrentDirectory();
var version = commandLineArgs.Options.GetOrNull(Options.Version.Short, Options.Version.Long);
if (updateNuget || !updateNpm)
{
await UpdateNugetPackages(commandLineArgs, directory);
await UpdateNugetPackages(commandLineArgs, directory, version);
}
if (updateNpm || !updateNuget)
{
await UpdateNpmPackages(directory);
await UpdateNpmPackages(directory, version);
}
}
private async Task UpdateNpmPackages(string directory)
private async Task UpdateNpmPackages(string directory, string version)
{
await _npmPackagesUpdater.Update(directory);
await _npmPackagesUpdater.Update(directory, version: version);
}
private async Task UpdateNugetPackages(CommandLineArgs commandLineArgs, string directory)
private async Task UpdateNugetPackages(CommandLineArgs commandLineArgs, string directory, string version)
{
var solution = commandLineArgs.Options.GetOrNull(Options.SolutionName.Short, Options.SolutionName.Long);
@ -66,7 +67,7 @@ namespace Volo.Abp.Cli.Commands
{
var solutionName = Path.GetFileName(solution).RemovePostFix(".sln");
await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, checkAll: checkAll);
await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, checkAll: checkAll, version: version);
Logger.LogInformation($"Volo packages are updated in {solutionName} solution.");
return;
@ -78,7 +79,7 @@ namespace Volo.Abp.Cli.Commands
{
var projectName = Path.GetFileName(project).RemovePostFix(".csproj");
await _nugetPackagesVersionUpdater.UpdateProjectAsync(project, checkAll: checkAll);
await _nugetPackagesVersionUpdater.UpdateProjectAsync(project, checkAll: checkAll, version: version);
Logger.LogInformation($"Volo packages are updated in {projectName} project.");
return;
@ -107,6 +108,7 @@ namespace Volo.Abp.Cli.Commands
sb.AppendLine("-sp|--solution-path (Specify the solution path)");
sb.AppendLine("-sn|--solution-name (Specify the solution name)");
sb.AppendLine("--check-all (Check the new version of each package separately)");
sb.AppendLine("-v|--version <version> (default: latest version)");
sb.AppendLine("");
sb.AppendLine("Some examples:");
sb.AppendLine("");
@ -148,6 +150,12 @@ namespace Volo.Abp.Cli.Commands
{
public const string Long = "check-all";
}
public static class Version
{
public const string Short = "v";
public const string Long = "version";
}
}
}
}

94
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs

@ -25,11 +25,11 @@ namespace Volo.Abp.Cli.ProjectModification
Logger = NullLogger<VoloNugetPackagesVersionUpdater>.Instance;
}
public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false, bool checkAll = false)
public async Task UpdateSolutionAsync(string solutionPath, bool includePreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false, bool checkAll = false, string version = null)
{
var projectPaths = ProjectFinder.GetProjectFiles(solutionPath);
if (checkAll)
if (checkAll && version.IsNullOrWhiteSpace())
{
Task.WaitAll(projectPaths.Select(projectPath => UpdateInternalAsync(projectPath, includePreviews, includeReleaseCandidates, switchToStable)).ToArray());
}
@ -48,7 +48,8 @@ namespace Volo.Abp.Cli.ProjectModification
switchToStable,
latestVersionFromNuget,
latestReleaseCandidateVersionFromNuget,
latestVersionFromMyGet);
latestVersionFromMyGet,
version);
File.WriteAllText(filePath, updatedContent);
}
@ -57,9 +58,9 @@ namespace Volo.Abp.Cli.ProjectModification
}
}
public async Task UpdateProjectAsync(string projectPath, bool includeNightlyPreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false, bool checkAll = false)
public async Task UpdateProjectAsync(string projectPath, bool includeNightlyPreviews = false, bool includeReleaseCandidates = false, bool switchToStable = false, bool checkAll = false, string version = null)
{
if (checkAll)
if (checkAll && version.IsNullOrWhiteSpace())
{
await UpdateInternalAsync(projectPath, includeNightlyPreviews, includeReleaseCandidates, switchToStable);
}
@ -77,7 +78,8 @@ namespace Volo.Abp.Cli.ProjectModification
switchToStable,
latestVersionFromNuget,
latestReleaseCandidateVersionFromNuget,
latestVersionFromMyGet);
latestVersionFromMyGet,
version);
File.WriteAllText(projectPath, updatedContent);
}
@ -91,13 +93,26 @@ namespace Volo.Abp.Cli.ProjectModification
File.WriteAllText(projectPath, updatedContent);
}
protected virtual async Task<bool> SpecifiedVersionExists(string version, string packageId)
{
var versionList = await _nuGetService.GetPackageVersionListAsync(packageId);
if (versionList.All(v => !v.Equals(version, StringComparison.OrdinalIgnoreCase)))
{
versionList = await _nuGetService.GetPackageVersionListAsync(packageId, true);
}
return versionList.Any(v => v.Equals(version, StringComparison.OrdinalIgnoreCase));
}
private async Task<string> UpdateVoloPackagesAsync(string content,
bool includeNightlyPreviews = false,
bool includeReleaseCandidates = false,
bool switchToStable = false,
SemanticVersion latestNugetVersion = null,
SemanticVersion latestNugetReleaseCandidateVersion = null,
string latestMyGetVersion = null)
string latestMyGetVersion = null,
string specifiedVersion = null)
{
string packageId = null;
@ -129,40 +144,63 @@ namespace Volo.Abp.Cli.ProjectModification
Logger.LogDebug("Checking package: \"{0}\" - Current version: {1}", packageId, currentSemanticVersion);
if ((includeNightlyPreviews || (currentVersion.Contains("-preview") && !switchToStable)) && !includeReleaseCandidates)
if (!specifiedVersion.IsNullOrWhiteSpace())
{
var latestVersion = latestMyGetVersion ?? await GetLatestVersionFromMyGet(packageId);
if (currentVersion != latestVersion)
if (await SpecifiedVersionExists(specifiedVersion, packageId))
{
Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentVersion, latestVersion);
versionAttribute.Value = latestVersion;
var specifiedSemanticVersion = SemanticVersion.Parse(specifiedVersion);
if (specifiedSemanticVersion > currentSemanticVersion)
{
Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentVersion, specifiedVersion);
versionAttribute.Value = specifiedVersion;
}
else
{
Logger.LogWarning("Unable to update package \"{0}\" version v{1} to v{2}.", packageId, currentVersion, specifiedVersion);
}
}
else
{
Logger.LogDebug("Package: \"{0}-v{1}\" is up to date.", packageId, currentVersion);
Logger.LogWarning("Package \"{0}\" specified version v{1} does not exist.", packageId, specifiedVersion);
}
}
else
{
SemanticVersion latestVersion;
if (currentSemanticVersion.IsPrerelease && !switchToStable)
{
latestVersion = latestNugetReleaseCandidateVersion ?? await _nuGetService.GetLatestVersionOrNullAsync(packageId, includeReleaseCandidates: true);
}
else
{
latestVersion = latestNugetVersion ?? await _nuGetService.GetLatestVersionOrNullAsync(packageId, includeReleaseCandidates: includeReleaseCandidates);
}
if (latestVersion != null && (currentSemanticVersion < latestVersion || (currentSemanticVersion.IsPrerelease && switchToStable)))
if ((includeNightlyPreviews || (currentVersion.Contains("-preview") && !switchToStable)) && !includeReleaseCandidates)
{
Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentSemanticVersion.ToString(), latestVersion.ToString());
versionAttribute.Value = latestVersion.ToString();
var latestVersion = latestMyGetVersion ?? await GetLatestVersionFromMyGet(packageId);
if (currentVersion != latestVersion)
{
Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentVersion, latestVersion);
versionAttribute.Value = latestVersion;
}
else
{
Logger.LogDebug("Package: \"{0}-v{1}\" is up to date.", packageId, currentVersion);
}
}
else
{
Logger.LogInformation("Package: \"{0}-v{1}\" is up to date.", packageId, currentSemanticVersion);
SemanticVersion latestVersion;
if (currentSemanticVersion.IsPrerelease && !switchToStable)
{
latestVersion = latestNugetReleaseCandidateVersion ?? await _nuGetService.GetLatestVersionOrNullAsync(packageId, includeReleaseCandidates: true);
}
else
{
latestVersion = latestNugetVersion ?? await _nuGetService.GetLatestVersionOrNullAsync(packageId, includeReleaseCandidates: includeReleaseCandidates);
}
if (latestVersion != null && (currentSemanticVersion < latestVersion || (currentSemanticVersion.IsPrerelease && switchToStable)))
{
Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentSemanticVersion.ToString(), latestVersion.ToString());
versionAttribute.Value = latestVersion.ToString();
}
else
{
Logger.LogInformation("Package: \"{0}-v{1}\" is up to date.", packageId, currentSemanticVersion);
}
}
}
}

12
framework/src/Volo.Abp.Cli/Volo/Abp/Cli/Program.cs

@ -3,13 +3,13 @@ using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Events;
using System.IO;
using Volo.Abp.Threading;
using System.Threading.Tasks;
namespace Volo.Abp.Cli
{
public class Program
{
private static void Main(string[] args)
private static async Task Main(string[] args)
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
@ -37,11 +37,9 @@ namespace Volo.Abp.Cli
{
application.Initialize();
AsyncHelper.RunSync(
() => application.ServiceProvider
.GetRequiredService<CliService>()
.RunAsync(args)
);
await application.ServiceProvider
.GetRequiredService<CliService>()
.RunAsync(args);
application.Shutdown();
}

51
framework/src/Volo.Abp.RabbitMQ/Volo/Abp/RabbitMQ/RabbitMqMessageConsumer.cs

@ -20,7 +20,7 @@ namespace Volo.Abp.RabbitMQ
protected IExceptionNotifier ExceptionNotifier { get; }
protected AbpTimer Timer { get; }
protected AbpAsyncTimer Timer { get; }
protected ExchangeDeclareConfiguration Exchange { get; private set; }
@ -38,7 +38,7 @@ namespace Volo.Abp.RabbitMQ
public RabbitMqMessageConsumer(
IConnectionPool connectionPool,
AbpTimer timer,
AbpAsyncTimer timer,
IExceptionNotifier exceptionNotifier)
{
ConnectionPool = connectionPool;
@ -50,7 +50,7 @@ namespace Volo.Abp.RabbitMQ
Callbacks = new ConcurrentBag<Func<IModel, BasicDeliverEventArgs, Task>>();
Timer.Period = 5000; //5 sec.
Timer.Elapsed += Timer_Elapsed;
Timer.Elapsed = Timer_Elapsed;
Timer.RunOnStart = true;
}
@ -77,7 +77,7 @@ namespace Volo.Abp.RabbitMQ
await TrySendQueueBindCommandsAsync();
}
protected virtual void TrySendQueueBindCommands()
protected virtual async Task TrySendQueueBindCommandsAsync()
{
try
{
@ -119,40 +119,33 @@ namespace Volo.Abp.RabbitMQ
catch (Exception ex)
{
Logger.LogException(ex, LogLevel.Warning);
AsyncHelper.RunSync(() => ExceptionNotifier.NotifyAsync(ex, logLevel: LogLevel.Warning));
await ExceptionNotifier.NotifyAsync(ex, logLevel: LogLevel.Warning);
}
}
protected virtual Task TrySendQueueBindCommandsAsync()
{
TrySendQueueBindCommands();
return Task.CompletedTask;
}
public virtual void OnMessageReceived(Func<IModel, BasicDeliverEventArgs, Task> callback)
{
Callbacks.Add(callback);
}
protected virtual void Timer_Elapsed(object sender, EventArgs e)
protected virtual async Task Timer_Elapsed(AbpAsyncTimer timer)
{
if (Channel == null || Channel.IsOpen == false)
{
TryCreateChannel();
TrySendQueueBindCommands();
await TryCreateChannelAsync();
await TrySendQueueBindCommandsAsync();
}
}
protected virtual void TryCreateChannel()
protected virtual async Task TryCreateChannelAsync()
{
DisposeChannel();
await DisposeChannelAsync();
try
{
var channel = ConnectionPool
.Get(ConnectionName)
.CreateModel();
channel.ExchangeDeclare(
exchange: Exchange.ExchangeName,
type: Exchange.Type,
@ -172,7 +165,7 @@ namespace Volo.Abp.RabbitMQ
var consumer = new EventingBasicConsumer(channel);
consumer.Received += async (model, basicDeliverEventArgs) =>
{
await HandleIncomingMessage(channel, basicDeliverEventArgs);
await HandleIncomingMessageAsync(channel, basicDeliverEventArgs);
};
channel.BasicConsume(
@ -186,11 +179,11 @@ namespace Volo.Abp.RabbitMQ
catch (Exception ex)
{
Logger.LogException(ex, LogLevel.Warning);
AsyncHelper.RunSync(() => ExceptionNotifier.NotifyAsync(ex, logLevel: LogLevel.Warning));
await ExceptionNotifier.NotifyAsync(ex, logLevel: LogLevel.Warning);
}
}
protected virtual async Task HandleIncomingMessage(IModel channel, BasicDeliverEventArgs basicDeliverEventArgs)
protected virtual async Task HandleIncomingMessageAsync(IModel channel, BasicDeliverEventArgs basicDeliverEventArgs)
{
try
{
@ -208,6 +201,24 @@ namespace Volo.Abp.RabbitMQ
}
}
protected virtual async Task DisposeChannelAsync()
{
if (Channel == null)
{
return;
}
try
{
Channel.Dispose();
}
catch (Exception ex)
{
Logger.LogException(ex, LogLevel.Warning);
await ExceptionNotifier.NotifyAsync(ex, logLevel: LogLevel.Warning);
}
}
protected virtual void DisposeChannel()
{
if (Channel == null)

127
framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AbpAsyncTimer.cs

@ -0,0 +1,127 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ExceptionHandling;
namespace Volo.Abp.Threading
{
/// <summary>
/// A robust timer implementation that ensures no overlapping occurs. It waits exactly specified <see cref="Period"/> between ticks.
/// </summary>
public class AbpAsyncTimer : ITransientDependency
{
/// <summary>
/// This func is raised periodically according to Period of Timer.
/// </summary>
public Func<AbpAsyncTimer, Task> Elapsed = _ => Task.CompletedTask;
/// <summary>
/// Task period of timer (as milliseconds).
/// </summary>
public int Period { get; set; }
/// <summary>
/// Indicates whether timer raises Elapsed event on Start method of Timer for once.
/// Default: False.
/// </summary>
public bool RunOnStart { get; set; }
public ILogger<AbpAsyncTimer> Logger { get; set; }
public IExceptionNotifier ExceptionNotifier { get; set; }
private readonly Timer _taskTimer;
private volatile bool _performingTasks;
private volatile bool _isRunning;
public AbpAsyncTimer()
{
ExceptionNotifier = NullExceptionNotifier.Instance;
Logger = NullLogger<AbpAsyncTimer>.Instance;
_taskTimer = new Timer(
TimerCallBack,
null,
Timeout.Infinite,
Timeout.Infinite
);
}
public void Start(CancellationToken cancellationToken = default)
{
if (Period <= 0)
{
throw new AbpException("Period should be set before starting the timer!");
}
lock (_taskTimer)
{
_taskTimer.Change(RunOnStart ? 0 : Period, Timeout.Infinite);
_isRunning = true;
}
}
public void Stop(CancellationToken cancellationToken = default)
{
lock (_taskTimer)
{
_taskTimer.Change(Timeout.Infinite, Timeout.Infinite);
while (_performingTasks)
{
Monitor.Wait(_taskTimer);
}
_isRunning = false;
}
}
/// <summary>
/// This method is called by _taskTimer.
/// </summary>
/// <param name="state">Not used argument</param>
private void TimerCallBack(object state)
{
lock (_taskTimer)
{
if (!_isRunning || _performingTasks)
{
return;
}
_taskTimer.Change(Timeout.Infinite, Timeout.Infinite);
_performingTasks = true;
}
_ = Timer_Elapsed();
}
private async Task Timer_Elapsed()
{
try
{
await Elapsed(this);
}
catch(Exception ex)
{
Logger.LogException(ex);
await ExceptionNotifier.NotifyAsync(ex);
}
finally
{
lock (_taskTimer)
{
_performingTasks = false;
if (_isRunning)
{
_taskTimer.Change(Period, Timeout.Infinite);
}
Monitor.Pulse(_taskTimer);
}
}
}
}
}

2
framework/src/Volo.Abp.Threading/Volo/Abp/Threading/AbpTimer.cs

@ -118,4 +118,4 @@ namespace Volo.Abp.Threading
}
}
}
}
}

4
framework/test/Volo.Abp.BlobStoring.Aws.Tests/Volo/Abp/BlobStoring/Aws/AbpBlobStoringAwsTestModule.cs

@ -69,7 +69,7 @@ namespace Volo.Abp.BlobStoring.Aws
private async Task DeleteBucketAsync(ApplicationShutdownContext context)
{
var amazonS3Client = await context.ServiceProvider.GetService<IAmazonS3ClientFactory>()
var amazonS3Client = await context.ServiceProvider.GetRequiredService<IAmazonS3ClientFactory>()
.GetAmazonS3Client(_configuration);
if (await AmazonS3Util.DoesS3BucketExistV2Async(amazonS3Client, _randomContainerName))
@ -89,4 +89,4 @@ namespace Volo.Abp.BlobStoring.Aws
}
}
}
}
}

987
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20201208084431_Added_CommitCount.Designer.cs

@ -0,0 +1,987 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Volo.Abp.EntityFrameworkCore;
using VoloDocs.EntityFrameworkCore;
namespace VoloDocs.EntityFrameworkCore.Migrations
{
[DbContext(typeof(VoloDocsDbContext))]
[Migration("20201208084431_Added_CommitCount")]
partial class Added_CommitCount
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.UseIdentityColumns()
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.0");
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Description")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsStatic")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("Regex")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<string>("RegexDescription")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<bool>("Required")
.HasColumnType("bit");
b.Property<int>("ValueType")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("AbpClaimTypes");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("SourceTenantId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("SourceUserId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TargetTenantId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("TargetUserId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId")
.IsUnique()
.HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL");
b.ToTable("AbpLinkUsers");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDefault")
.HasColumnType("bit")
.HasColumnName("IsDefault");
b.Property<bool>("IsPublic")
.HasColumnType("bit")
.HasColumnName("IsPublic");
b.Property<bool>("IsStatic")
.HasColumnType("bit")
.HasColumnName("IsStatic");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("NormalizedName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("NormalizedName");
b.ToTable("AbpRoles");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("ClaimType")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("ClaimValue")
.HasMaxLength(1024)
.HasColumnType("nvarchar(1024)");
b.Property<Guid>("RoleId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Action")
.HasMaxLength(96)
.HasColumnType("nvarchar(96)");
b.Property<string>("ApplicationName")
.HasMaxLength(96)
.HasColumnType("nvarchar(96)");
b.Property<string>("BrowserInfo")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<string>("ClientId")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ClientIpAddress")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("CorrelationId")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("Identity")
.HasMaxLength(96)
.HasColumnType("nvarchar(96)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("TenantName")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.HasKey("Id");
b.HasIndex("TenantId", "Action");
b.HasIndex("TenantId", "ApplicationName");
b.HasIndex("TenantId", "Identity");
b.HasIndex("TenantId", "UserId");
b.ToTable("AbpSecurityLogs");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<int>("AccessFailedCount")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasDefaultValue(0)
.HasColumnName("AccessFailedCount");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("Email");
b.Property<bool>("EmailConfirmed")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("EmailConfirmed");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<bool>("IsExternal")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsExternal");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<bool>("LockoutEnabled")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("LockoutEnabled");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("Name")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("Name");
b.Property<string>("NormalizedEmail")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("NormalizedEmail");
b.Property<string>("NormalizedUserName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("NormalizedUserName");
b.Property<string>("PasswordHash")
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("PasswordHash");
b.Property<string>("PhoneNumber")
.HasMaxLength(16)
.HasColumnType("nvarchar(16)")
.HasColumnName("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("PhoneNumberConfirmed");
b.Property<string>("SecurityStamp")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("SecurityStamp");
b.Property<string>("Surname")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)")
.HasColumnName("Surname");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<bool>("TwoFactorEnabled")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("TwoFactorEnabled");
b.Property<string>("UserName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)")
.HasColumnName("UserName");
b.HasKey("Id");
b.HasIndex("Email");
b.HasIndex("NormalizedEmail");
b.HasIndex("NormalizedUserName");
b.HasIndex("UserName");
b.ToTable("AbpUsers");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("ClaimType")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("ClaimValue")
.HasMaxLength(1024)
.HasColumnType("nvarchar(1024)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AbpUserClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("LoginProvider")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ProviderDisplayName")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(196)
.HasColumnType("nvarchar(196)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("UserId", "LoginProvider");
b.HasIndex("LoginProvider", "ProviderKey");
b.ToTable("AbpUserLogins");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b =>
{
b.Property<Guid>("OrganizationUnitId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("OrganizationUnitId", "UserId");
b.HasIndex("UserId", "OrganizationUnitId");
b.ToTable("AbpUserOrganizationUnits");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("RoleId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId", "UserId");
b.ToTable("AbpUserRoles");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("LoginProvider")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("Name")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AbpUserTokens");
});
modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Code")
.IsRequired()
.HasMaxLength(95)
.HasColumnType("nvarchar(95)")
.HasColumnName("Code");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uniqueidentifier")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime2")
.HasColumnName("DeletionTime");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uniqueidentifier")
.HasColumnName("LastModifierId");
b.Property<Guid?>("ParentId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("Code");
b.HasIndex("ParentId");
b.ToTable("AbpOrganizationUnits");
});
modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b =>
{
b.Property<Guid>("OrganizationUnitId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("RoleId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("OrganizationUnitId", "RoleId");
b.HasIndex("RoleId", "OrganizationUnitId");
b.ToTable("AbpOrganizationUnitRoles");
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ProviderName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpPermissionGrants");
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("ProviderName")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("nvarchar(2048)");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpSettings");
});
modelBuilder.Entity("Volo.Docs.Documents.Document", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("EditLink")
.HasMaxLength(2048)
.HasColumnType("nvarchar(2048)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("FileName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("Format")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("LanguageCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<DateTime>("LastCachedTime")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastSignificantUpdateTime")
.HasColumnType("datetime2");
b.Property<DateTime>("LastUpdatedTime")
.HasColumnType("datetime2");
b.Property<string>("LocalDirectory")
.HasMaxLength(512)
.HasColumnType("nvarchar(512)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("nvarchar(255)");
b.Property<Guid>("ProjectId")
.HasColumnType("uniqueidentifier");
b.Property<string>("RawRootUrl")
.HasMaxLength(2048)
.HasColumnType("nvarchar(2048)");
b.Property<string>("RootUrl")
.HasMaxLength(2048)
.HasColumnType("nvarchar(2048)");
b.Property<string>("Version")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.HasKey("Id");
b.ToTable("DocsDocuments");
});
modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b =>
{
b.Property<Guid>("DocumentId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Username")
.HasColumnType("nvarchar(450)");
b.Property<string>("AvatarUrl")
.HasColumnType("nvarchar(max)");
b.Property<int>("CommitCount")
.HasColumnType("int");
b.Property<string>("UserProfileUrl")
.HasColumnType("nvarchar(max)");
b.HasKey("DocumentId", "Username");
b.ToTable("DocsDocumentContributors");
});
modelBuilder.Entity("Volo.Docs.Projects.Project", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("nvarchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("DefaultDocumentName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("DocumentStoreType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ExtraProperties")
.HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties");
b.Property<string>("Format")
.HasColumnType("nvarchar(max)");
b.Property<string>("LatestVersionBranchName")
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("MainWebsiteUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("MinimumVersion")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("NavigationDocumentName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ParametersDocumentName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("nvarchar(128)");
b.Property<string>("ShortName")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("nvarchar(32)");
b.HasKey("Id");
b.ToTable("DocsProjects");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole", null)
.WithMany("Claims")
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Claims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Logins")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b =>
{
b.HasOne("Volo.Abp.Identity.OrganizationUnit", null)
.WithMany()
.HasForeignKey("OrganizationUnitId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("OrganizationUnits")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Roles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Tokens")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b =>
{
b.HasOne("Volo.Abp.Identity.OrganizationUnit", null)
.WithMany()
.HasForeignKey("ParentId");
});
modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b =>
{
b.HasOne("Volo.Abp.Identity.OrganizationUnit", null)
.WithMany("Roles")
.HasForeignKey("OrganizationUnitId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Volo.Abp.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b =>
{
b.HasOne("Volo.Docs.Documents.Document", null)
.WithMany("Contributors")
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
{
b.Navigation("Claims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Navigation("Claims");
b.Navigation("Logins");
b.Navigation("OrganizationUnits");
b.Navigation("Roles");
b.Navigation("Tokens");
});
modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b =>
{
b.Navigation("Roles");
});
modelBuilder.Entity("Volo.Docs.Documents.Document", b =>
{
b.Navigation("Contributors");
});
#pragma warning restore 612, 618
}
}
}

24
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20201208084431_Added_CommitCount.cs

@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace VoloDocs.EntityFrameworkCore.Migrations
{
public partial class Added_CommitCount : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "CommitCount",
table: "DocsDocumentContributors",
type: "int",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CommitCount",
table: "DocsDocumentContributors");
}
}
}

5
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/VoloDocsDbContextModelSnapshot.cs

@ -19,7 +19,7 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
.UseIdentityColumns()
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.0-rc.2.20475.6");
.HasAnnotation("ProductVersion", "5.0.0");
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
@ -782,6 +782,9 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
b.Property<string>("AvatarUrl")
.HasColumnType("nvarchar(max)");
b.Property<int>("CommitCount")
.HasColumnType("int");
b.Property<string>("UserProfileUrl")
.HasColumnType("nvarchar(max)");

2
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentContributorDto.cs

@ -10,5 +10,7 @@ namespace Volo.Docs.Documents
public string UserProfileUrl { get; set; }
public string AvatarUrl { get; set; }
public int CommitCount { get; set; }
}
}

4
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/Document.cs

@ -87,9 +87,9 @@ namespace Volo.Docs.Documents
Contributors = new List<DocumentContributor>();
}
public virtual void AddContributor(string username, string userProfileUrl, string avatarUrl)
public virtual void AddContributor(string username, string userProfileUrl, string avatarUrl, int commitCount = 1)
{
Contributors.AddIfNotContains(new DocumentContributor(Id, username, userProfileUrl, avatarUrl));
Contributors.AddIfNotContains(new DocumentContributor(Id, username, userProfileUrl, avatarUrl, commitCount));
}
public virtual void RemoveAllContributors()

5
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentContributor.cs

@ -9,6 +9,8 @@ namespace Volo.Docs.Documents
public string Username { get; set; }
public int CommitCount { get; set; }
public string UserProfileUrl { get; set; }
public string AvatarUrl { get; set; }
@ -23,12 +25,13 @@ namespace Volo.Docs.Documents
return DocumentId == documentId && Username == username;
}
public DocumentContributor(Guid documentId, string username, string userProfileUrl, string avatarUrl)
public DocumentContributor(Guid documentId, string username, string userProfileUrl, string avatarUrl, int commitCount = 1)
{
DocumentId = documentId;
Username = username;
UserProfileUrl = userProfileUrl;
AvatarUrl = avatarUrl;
CommitCount = commitCount;
}
public override object[] GetKeys()

13
modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/DocumentAuthor.cs

@ -0,0 +1,13 @@
namespace Volo.Docs.GitHub.Documents
{
public class DocumentAuthor
{
public string Login { get; set; }
public string HtmlUrl { get; set; }
public string AvatarUrl { get; set; }
public int CommitCount { get; set; }
}
}

31
modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs

@ -84,9 +84,11 @@ namespace Volo.Docs.GitHub.Documents
}
var authors = GetAuthors(commits);
document.RemoveAllContributors();
foreach (var author in authors)
{
document.AddContributor(author.Login, author.HtmlUrl, author.AvatarUrl);
document.AddContributor(author.Login, author.HtmlUrl, author.AvatarUrl, author.CommitCount);
}
return document;
@ -114,20 +116,35 @@ namespace Volo.Docs.GitHub.Documents
: null;
}
private static List<Author> GetAuthors(IReadOnlyList<GitHubCommit> commits)
private static List<DocumentAuthor> GetAuthors(IReadOnlyList<GitHubCommit> commits)
{
if (commits == null || !commits.Any())
{
return new List<Author>();
return new List<DocumentAuthor>();
}
return commits
var authorsOrderedAndGrouped = commits
.Where(x => x.Author != null)
.Select(x => x.Author)
.GroupBy(x => x.Id)
.OrderByDescending(x => x.Count())
.Select(x => x.FirstOrDefault())
.ToList();
.OrderByDescending(x => x.Count());
var documentAuthors = new List<DocumentAuthor>();
foreach (var authorGroup in authorsOrderedAndGrouped)
{
var author = authorGroup.FirstOrDefault();
var documentAuthor = new DocumentAuthor
{
CommitCount = authorGroup.Count(),
AvatarUrl = author.AvatarUrl,
HtmlUrl = author.HtmlUrl,
Login = author.Login
};
documentAuthors.Add(documentAuthor);
}
return documentAuthors;
}
private static DateTime GetLastCommitDate(IReadOnlyList<GitHubCommit> commits)

2
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml

@ -217,7 +217,7 @@
<span class="for-desktop mr-3">
@(L["Contributors"].Value)
</span>
@foreach (var contributor in Model.Document.Contributors)
@foreach (var contributor in Model.Document.Contributors.OrderByDescending(c=> c.CommitCount).ToList())
{
<a href="@contributor.UserProfileUrl" target="_blank" class="cont-avatar">
<img src="@contributor.AvatarUrl"

7
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Tokens/TokenCleanupBackgroundWorker.cs

@ -11,11 +11,11 @@ namespace Volo.Abp.IdentityServer.Tokens
protected TokenCleanupOptions Options { get; }
public TokenCleanupBackgroundWorker(
AbpTimer timer,
AbpAsyncTimer timer,
IServiceScopeFactory serviceScopeFactory,
IOptions<TokenCleanupOptions> options)
: base(
timer,
timer,
serviceScopeFactory)
{
Options = options.Value;
@ -27,8 +27,7 @@ namespace Volo.Abp.IdentityServer.Tokens
await workerContext
.ServiceProvider
.GetRequiredService<TokenCleanupService>()
.CleanAsync()
;
.CleanAsync();
}
}
}

Loading…
Cancel
Save