Browse Source

V3.0 (#452)

* Architectural refactoring

* Add new memory serializer

* code refactor

* Add service inject

* update to publish

* Fix message consumer bugs

* upgrade to netcoreapp3.0

* remove discoverys code

* remove unused files

* Code refactor

* code cleanup

* remove unused file

* upgrade nuget and upgrade framework to netstandard 2.1

* add async support for CAPTransaction

* bug fixed

* Typo: "Getting Stared"

* Add dashboard api interface

* Add Nodediscovry

* remove unused file

* upgrade dashoboard module

* Rename file

* Refactoring postgresql implementation for version 3.0

* Fixed mysql dashboard query bug

* Code refactoring

* Refactoring sqlserver implementation for version 3.0

* Refactoring mongo implementation for version 3.0

* Add index for mysql table

* Fixed sqlserver connection async issue

* Refactoring kafka transport implementation for version 3.0

* Refactoring inmemory storage implementation for version 3.0

* Refactoring azure serverbus transport  implementation for version 3.0

* Update samples to netcoreapp3.0

* Refactoring namespace

* Change System.Text.Json to Json.NET

* Code refactoring

* Rename class

* Fix obsolete

* Fix kafka consumer client bugs

* Fix sql reader  column index error

* Introduced rewrite table name option

* Introduced rewrite table name option

* Introduced rewrite table name option for pgsql

* Introduced rewrite table name option

* Fix SqlServer service injection bug

* Fix sql bug

* Fix Kafka transport check not working bug. #436

* code cleanup

* update samples

* Adjust dashboard display

* Refacing diagnostics tracing module.

* Code cleanup

* Remove outdated unit tests

* Add sync publish method with additional header

* update version to 3.0

* Add fake transport fot unit tests

* Support null value of message body.

* Rename class

* Rename class

* Fix mysql unit tests

* Fix  loops when configuration items are abnormal or unreachable. #444

* Refactoring

* Add sqlsever samples

* Schema renaming to lowercase is more conformant

* Fix SQL Server tranaction error in entityframework. #402

* update readme

* update ci yml

* Remove the database integration test

* fix build error

* upgrade mongo nuget package to 2.10.0, because 2.8.0  have bugs in .net core 3.0

* Fix mongodb dashboard query bugs

* update samples

* Fix postgresql storage bugs

* Fix build error

* Fix unit tests

* Fix build errorFix unit tests

* Add Kafka options to support  custom header to add offset and partition into CapHeader.  #374
master
Savorboard 4 years ago
committed by GitHub
parent
commit
aaecabe589
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
100 changed files with 1068 additions and 245 deletions
  1. +1
    -1
      .travis.yml
  2. +29
    -33
      CAP.sln
  3. +5
    -1
      README.md
  4. +6
    -0
      README.zh-cn.md
  5. +1
    -6
      appveyor.yml
  6. +3
    -3
      build/version.props
  7. +1
    -1
      docs/mkdocs.yml
  8. +0
    -19
      samples/Sample.AzureServiceBus.InMemory/Program.cs
  9. +1
    -1
      samples/Sample.Kafka.InMemory/Controllers/ValuesController.cs
  10. +20
    -0
      samples/Sample.Kafka.InMemory/Program.cs
  11. +4
    -6
      samples/Sample.Kafka.InMemory/Sample.Kafka.InMemory.csproj
  12. +8
    -4
      samples/Sample.Kafka.InMemory/Startup.cs
  13. +0
    -0
      samples/Sample.Kafka.InMemory/appsettings.json
  14. +0
    -19
      samples/Sample.Kafka.MySql/Program.cs
  15. +7
    -10
      samples/Sample.Kafka.PostgreSql/Controllers/ValuesController.cs
  16. +20
    -0
      samples/Sample.Kafka.PostgreSql/Program.cs
  17. +4
    -6
      samples/Sample.Kafka.PostgreSql/Sample.Kafka.PostgreSql.csproj
  18. +10
    -7
      samples/Sample.Kafka.PostgreSql/Startup.cs
  19. +0
    -0
      samples/Sample.Kafka.PostgreSql/appsettings.json
  20. +2
    -4
      samples/Sample.RabbitMQ.MongoDB/Sample.RabbitMQ.MongoDB.csproj
  21. +7
    -11
      samples/Sample.RabbitMQ.MongoDB/Startup.cs
  22. +16
    -1
      samples/Sample.RabbitMQ.MySql/AppDbContext.cs
  23. +21
    -12
      samples/Sample.RabbitMQ.MySql/Controllers/ValuesController.cs
  24. +9
    -7
      samples/Sample.RabbitMQ.MySql/Program.cs
  25. +7
    -6
      samples/Sample.RabbitMQ.MySql/Properties/launchSettings.json
  26. +4
    -4
      samples/Sample.RabbitMQ.MySql/Sample.RabbitMQ.MySql.csproj
  27. +12
    -8
      samples/Sample.RabbitMQ.MySql/Startup.cs
  28. +1
    -1
      samples/Sample.RabbitMQ.MySql/appsettings.json
  29. +40
    -0
      samples/Sample.RabbitMQ.SqlServer/AppDbContext.cs
  30. +76
    -0
      samples/Sample.RabbitMQ.SqlServer/Controllers/ValuesController.cs
  31. +40
    -0
      samples/Sample.RabbitMQ.SqlServer/Migrations/20191205032949_FirstMigration.Designer.cs
  32. +29
    -0
      samples/Sample.RabbitMQ.SqlServer/Migrations/20191205032949_FirstMigration.cs
  33. +38
    -0
      samples/Sample.RabbitMQ.SqlServer/Migrations/AppDbContextModelSnapshot.cs
  34. +20
    -0
      samples/Sample.RabbitMQ.SqlServer/Program.cs
  35. +22
    -0
      samples/Sample.RabbitMQ.SqlServer/Sample.RabbitMQ.SqlServer.csproj
  36. +39
    -0
      samples/Sample.RabbitMQ.SqlServer/Startup.cs
  37. +8
    -0
      samples/Sample.RabbitMQ.SqlServer/appsettings.json
  38. +1
    -1
      src/Directory.Build.props
  39. +8
    -7
      src/DotNetCore.CAP.AzureServiceBus/AzureServiceBusConsumerClient.cs
  40. +1
    -0
      src/DotNetCore.CAP.AzureServiceBus/AzureServiceBusConsumerClientFactory.cs
  41. +0
    -1
      src/DotNetCore.CAP.AzureServiceBus/CAP.AzureServiceBusOptions.cs
  42. +2
    -2
      src/DotNetCore.CAP.AzureServiceBus/CAP.AzureServiceBusOptionsExtension.cs
  43. +19
    -20
      src/DotNetCore.CAP.AzureServiceBus/ITransport.AzureServiceBus.cs
  44. +128
    -0
      src/DotNetCore.CAP.Dashboard/AwaitableInfo.cs
  45. +0
    -0
      src/DotNetCore.CAP.Dashboard/BatchCommandDispatcher.cs
  46. +72
    -2
      src/DotNetCore.CAP.Dashboard/CAP.DashboardMiddleware.cs
  47. +0
    -0
      src/DotNetCore.CAP.Dashboard/CAP.DashboardOptions.cs
  48. +3
    -0
      src/DotNetCore.CAP.Dashboard/CAP.DashboardOptionsExtensions.cs
  49. +1
    -1
      src/DotNetCore.CAP.Dashboard/CapCache.cs
  50. +44
    -0
      src/DotNetCore.CAP.Dashboard/CoercedAwaitableInfo.cs
  51. +4
    -4
      src/DotNetCore.CAP.Dashboard/CombinedResourceDispatcher.cs
  52. +0
    -0
      src/DotNetCore.CAP.Dashboard/CommandDispatcher.cs
  53. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/css/bootstrap.min.css
  54. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/css/cap.css
  55. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/css/jsonview.min.css
  56. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/css/rickshaw.min.css
  57. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.eot
  58. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.svg
  59. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.ttf
  60. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.woff
  61. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.woff2
  62. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/bootstrap.min.js
  63. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/cap.js
  64. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/d3.layout.min.js
  65. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/d3.min.js
  66. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/jquery-2.1.4.min.js
  67. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/jsonview.min.js
  68. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/moment-with-locales.min.js
  69. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/moment.min.js
  70. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/js/rickshaw.min.js
  71. +1
    -1
      src/DotNetCore.CAP.Dashboard/Content/resx/Strings.Designer.cs
  72. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/resx/Strings.resx
  73. +0
    -0
      src/DotNetCore.CAP.Dashboard/Content/resx/Strings.zh.resx
  74. +4
    -3
      src/DotNetCore.CAP.Dashboard/DashboardContext.cs
  75. +0
    -0
      src/DotNetCore.CAP.Dashboard/DashboardMetric.cs
  76. +0
    -0
      src/DotNetCore.CAP.Dashboard/DashboardMetrics.cs
  77. +0
    -0
      src/DotNetCore.CAP.Dashboard/DashboardRequest.cs
  78. +0
    -0
      src/DotNetCore.CAP.Dashboard/DashboardResponse.cs
  79. +7
    -5
      src/DotNetCore.CAP.Dashboard/DashboardRoutes.cs
  80. +239
    -0
      src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj
  81. +2
    -4
      src/DotNetCore.CAP.Dashboard/EmbeddedResourceDispatcher.cs
  82. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/DownstreamUrl.cs
  83. +1
    -1
      src/DotNetCore.CAP.Dashboard/GatewayProxy/GatewayProxyMiddleware.cs
  84. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/IRequestMapper.Default.cs
  85. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/IRequestMapper.cs
  86. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/HttpClientBuilder.cs
  87. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/HttpClientHttpRequester.cs
  88. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClient.cs
  89. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClientBuilder.cs
  90. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClientCache.cs
  91. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpRequester.cs
  92. +0
    -0
      src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/MemoryHttpClientCache.cs
  93. +2
    -2
      src/DotNetCore.CAP.Dashboard/HtmlHelper.cs
  94. +0
    -0
      src/DotNetCore.CAP.Dashboard/IDashboardAuthorizationFilter.cs
  95. +0
    -0
      src/DotNetCore.CAP.Dashboard/IDashboardDispatcher.cs
  96. +1
    -1
      src/DotNetCore.CAP.Dashboard/JsonDispatcher.cs
  97. +1
    -1
      src/DotNetCore.CAP.Dashboard/JsonStats.cs
  98. +7
    -9
      src/DotNetCore.CAP.Dashboard/LocalRequestsOnlyAuthorizationFilter.cs
  99. +0
    -0
      src/DotNetCore.CAP.Dashboard/MenuItem.cs
  100. +9
    -9
      src/DotNetCore.CAP.Dashboard/MessageHistoryRenderer.cs

+ 1
- 1
.travis.yml View File

@@ -2,7 +2,7 @@ language: csharp
sudo: required
dist: xenial
solution: CAP.sln
dotnet: 2.2
dotnet: 3.0
mono: none

#matrix:


+ 29
- 33
CAP.sln View File

@@ -42,8 +42,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.Test", "test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.SqlServer", "src\DotNetCore.CAP.SqlServer\DotNetCore.CAP.SqlServer.csproj", "{3B577468-6792-4EF1-9237-15180B176A24}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.SqlServer.Test", "test\DotNetCore.CAP.SqlServer.Test\DotNetCore.CAP.SqlServer.Test.csproj", "{DA00FA38-C4B9-4F55-8756-D480FBC1084F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.MySql", "src\DotNetCore.CAP.MySql\DotNetCore.CAP.MySql.csproj", "{FA15685A-778A-4D2A-A2FE-27FAD2FFA65B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.MySql.Test", "test\DotNetCore.CAP.MySql.Test\DotNetCore.CAP.MySql.Test.csproj", "{80A84F62-1558-427B-BA74-B47AA8A665B5}"
@@ -52,21 +50,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.RabbitMQ.MySql", "sa
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.PostgreSql", "src\DotNetCore.CAP.PostgreSql\DotNetCore.CAP.PostgreSql.csproj", "{82C403AB-ED68-4084-9A1D-11334F9F08F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.PostgreSql.Test", "test\DotNetCore.CAP.PostgreSql.Test\DotNetCore.CAP.PostgreSql.Test.csproj", "{7CA3625D-1817-4695-881D-7E79A1E1DED2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.MongoDB.Test", "test\DotNetCore.CAP.MongoDB.Test\DotNetCore.CAP.MongoDB.Test.csproj", "{C143FCDF-E7F3-46F8-987E-A1BA38C1639D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.MongoDB", "src\DotNetCore.CAP.MongoDB\DotNetCore.CAP.MongoDB.csproj", "{77C0AC02-C44B-49D5-B969-7D5305FC20A5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.RabbitMQ.MongoDB", "samples\Sample.RabbitMQ.MongoDB\Sample.RabbitMQ.MongoDB.csproj", "{4473DE19-E8D2-4B57-80A8-C8AAA2BFA20F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Kafka.MySql", "samples\Sample.Kafka.MySql\Sample.Kafka.MySql.csproj", "{11563D1A-27CC-45CF-8C04-C16BCC21250A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.AzureServiceBus", "src\DotNetCore.CAP.AzureServiceBus\DotNetCore.CAP.AzureServiceBus.csproj", "{63B2A464-FBEA-42FB-8EFA-98AFA39FC920}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.InMemoryStorage", "src\DotNetCore.CAP.InMemoryStorage\DotNetCore.CAP.InMemoryStorage.csproj", "{58B6E829-C6C8-457C-9DD0-C600650254DF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AzureServiceBus.InMemory", "samples\Sample.AzureServiceBus.InMemory\Sample.AzureServiceBus.InMemory.csproj", "{1E1E959C-3D0E-45C3-ABCA-DAAACE68AAB8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.Dashboard", "src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj", "{56FB261C-67AF-4715-9A46-4FA4FAB91B2C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Kafka.InMemory", "samples\Sample.Kafka.InMemory\Sample.Kafka.InMemory.csproj", "{1B0371D6-36A4-4C78-A727-8ED732FDBA1D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.RabbitMQ.SqlServer", "samples\Sample.RabbitMQ.SqlServer\Sample.RabbitMQ.SqlServer.csproj", "{F6C5C676-AF05-46D5-A45D-442137B31898}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Kafka.PostgreSql", "samples\Sample.Kafka.PostgreSql\Sample.Kafka.PostgreSql.csproj", "{F1EF1D26-8A6B-403E-85B0-250DF44A4A7C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -93,10 +91,6 @@ Global
{3B577468-6792-4EF1-9237-15180B176A24}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B577468-6792-4EF1-9237-15180B176A24}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B577468-6792-4EF1-9237-15180B176A24}.Release|Any CPU.Build.0 = Release|Any CPU
{DA00FA38-C4B9-4F55-8756-D480FBC1084F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA00FA38-C4B9-4F55-8756-D480FBC1084F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA00FA38-C4B9-4F55-8756-D480FBC1084F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA00FA38-C4B9-4F55-8756-D480FBC1084F}.Release|Any CPU.Build.0 = Release|Any CPU
{FA15685A-778A-4D2A-A2FE-27FAD2FFA65B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA15685A-778A-4D2A-A2FE-27FAD2FFA65B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA15685A-778A-4D2A-A2FE-27FAD2FFA65B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -106,30 +100,21 @@ Global
{80A84F62-1558-427B-BA74-B47AA8A665B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80A84F62-1558-427B-BA74-B47AA8A665B5}.Release|Any CPU.Build.0 = Release|Any CPU
{9F3F9BFE-7B6A-4A7A-A6E6-8B517D611873}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9F3F9BFE-7B6A-4A7A-A6E6-8B517D611873}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9F3F9BFE-7B6A-4A7A-A6E6-8B517D611873}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9F3F9BFE-7B6A-4A7A-A6E6-8B517D611873}.Release|Any CPU.Build.0 = Release|Any CPU
{82C403AB-ED68-4084-9A1D-11334F9F08F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82C403AB-ED68-4084-9A1D-11334F9F08F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82C403AB-ED68-4084-9A1D-11334F9F08F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82C403AB-ED68-4084-9A1D-11334F9F08F9}.Release|Any CPU.Build.0 = Release|Any CPU
{7CA3625D-1817-4695-881D-7E79A1E1DED2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7CA3625D-1817-4695-881D-7E79A1E1DED2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CA3625D-1817-4695-881D-7E79A1E1DED2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CA3625D-1817-4695-881D-7E79A1E1DED2}.Release|Any CPU.Build.0 = Release|Any CPU
{C143FCDF-E7F3-46F8-987E-A1BA38C1639D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C143FCDF-E7F3-46F8-987E-A1BA38C1639D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C143FCDF-E7F3-46F8-987E-A1BA38C1639D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C143FCDF-E7F3-46F8-987E-A1BA38C1639D}.Release|Any CPU.Build.0 = Release|Any CPU
{77C0AC02-C44B-49D5-B969-7D5305FC20A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77C0AC02-C44B-49D5-B969-7D5305FC20A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77C0AC02-C44B-49D5-B969-7D5305FC20A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77C0AC02-C44B-49D5-B969-7D5305FC20A5}.Release|Any CPU.Build.0 = Release|Any CPU
{4473DE19-E8D2-4B57-80A8-C8AAA2BFA20F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4473DE19-E8D2-4B57-80A8-C8AAA2BFA20F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4473DE19-E8D2-4B57-80A8-C8AAA2BFA20F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4473DE19-E8D2-4B57-80A8-C8AAA2BFA20F}.Release|Any CPU.Build.0 = Release|Any CPU
{11563D1A-27CC-45CF-8C04-C16BCC21250A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11563D1A-27CC-45CF-8C04-C16BCC21250A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11563D1A-27CC-45CF-8C04-C16BCC21250A}.Release|Any CPU.Build.0 = Release|Any CPU
{63B2A464-FBEA-42FB-8EFA-98AFA39FC920}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63B2A464-FBEA-42FB-8EFA-98AFA39FC920}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63B2A464-FBEA-42FB-8EFA-98AFA39FC920}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -138,10 +123,22 @@ Global
{58B6E829-C6C8-457C-9DD0-C600650254DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58B6E829-C6C8-457C-9DD0-C600650254DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58B6E829-C6C8-457C-9DD0-C600650254DF}.Release|Any CPU.Build.0 = Release|Any CPU
{1E1E959C-3D0E-45C3-ABCA-DAAACE68AAB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E1E959C-3D0E-45C3-ABCA-DAAACE68AAB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E1E959C-3D0E-45C3-ABCA-DAAACE68AAB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E1E959C-3D0E-45C3-ABCA-DAAACE68AAB8}.Release|Any CPU.Build.0 = Release|Any CPU
{56FB261C-67AF-4715-9A46-4FA4FAB91B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56FB261C-67AF-4715-9A46-4FA4FAB91B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56FB261C-67AF-4715-9A46-4FA4FAB91B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56FB261C-67AF-4715-9A46-4FA4FAB91B2C}.Release|Any CPU.Build.0 = Release|Any CPU
{1B0371D6-36A4-4C78-A727-8ED732FDBA1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1B0371D6-36A4-4C78-A727-8ED732FDBA1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1B0371D6-36A4-4C78-A727-8ED732FDBA1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1B0371D6-36A4-4C78-A727-8ED732FDBA1D}.Release|Any CPU.Build.0 = Release|Any CPU
{F6C5C676-AF05-46D5-A45D-442137B31898}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F6C5C676-AF05-46D5-A45D-442137B31898}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F6C5C676-AF05-46D5-A45D-442137B31898}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F6C5C676-AF05-46D5-A45D-442137B31898}.Release|Any CPU.Build.0 = Release|Any CPU
{F1EF1D26-8A6B-403E-85B0-250DF44A4A7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F1EF1D26-8A6B-403E-85B0-250DF44A4A7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F1EF1D26-8A6B-403E-85B0-250DF44A4A7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1EF1D26-8A6B-403E-85B0-250DF44A4A7C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -152,19 +149,18 @@ Global
{9961B80E-0718-4280-B2A0-271B003DE26B} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{F608B509-A99B-4AC7-8227-42051DD4A578} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0}
{3B577468-6792-4EF1-9237-15180B176A24} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{DA00FA38-C4B9-4F55-8756-D480FBC1084F} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0}
{FA15685A-778A-4D2A-A2FE-27FAD2FFA65B} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{80A84F62-1558-427B-BA74-B47AA8A665B5} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0}
{9F3F9BFE-7B6A-4A7A-A6E6-8B517D611873} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{82C403AB-ED68-4084-9A1D-11334F9F08F9} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{7CA3625D-1817-4695-881D-7E79A1E1DED2} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0}
{C143FCDF-E7F3-46F8-987E-A1BA38C1639D} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0}
{77C0AC02-C44B-49D5-B969-7D5305FC20A5} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{4473DE19-E8D2-4B57-80A8-C8AAA2BFA20F} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{11563D1A-27CC-45CF-8C04-C16BCC21250A} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{63B2A464-FBEA-42FB-8EFA-98AFA39FC920} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{58B6E829-C6C8-457C-9DD0-C600650254DF} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{1E1E959C-3D0E-45C3-ABCA-DAAACE68AAB8} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{56FB261C-67AF-4715-9A46-4FA4FAB91B2C} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{1B0371D6-36A4-4C78-A727-8ED732FDBA1D} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{F6C5C676-AF05-46D5-A45D-442137B31898} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{F1EF1D26-8A6B-403E-85B0-250DF44A4A7C} = {3A6B6931-A123-477A-9469-8B468B5385AF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2E70565D-94CF-40B4-BFE1-AC18D5F736AB}


+ 5
- 1
README.md View File

@@ -224,7 +224,11 @@ services.AddCap(x =>

### Dashboard

CAP v2.1+ provides the dashboard pages, you can easily view the sent and received messages. In addition, you can also view the message status in real time on the dashboard.
CAP v2.1+ provides the dashboard pages, you can easily view the sent and received messages. In addition, you can also view the message status in real time on the dashboard. Use the following command to install the Dashboard in your project.

```
PM> Install-Package DotNetCore.Dashboard
```

In the distributed environment, the dashboard built-in integrated [Consul](http://consul.io) as a node discovery, while the realization of the gateway agent function, you can also easily view the node or other node data, It's like you are visiting local resources.



+ 6
- 0
README.zh-cn.md View File

@@ -239,6 +239,12 @@ services.AddCap(x =>

CAP 2.1+ 以上版本中提供了仪表盘(Dashboard)功能,你可以很方便的查看发出和接收到的消息。除此之外,你还可以在仪表盘中实时查看发送或者接收到的消息。

使用一下命令安装 Dashboard:

```
PM> Install-Package DotNetCore.Dashboard
```

在分布式环境中,仪表盘内置集成了 [Consul](http://consul.io) 作为节点的注册发现,同时实现了网关代理功能,你同样可以方便的查看本节点或者其他节点的数据,它就像你访问本地资源一样。

```c#


+ 1
- 6
appveyor.yml View File

@@ -1,16 +1,11 @@
version: '{build}'
os: Visual Studio 2017
os: Visual Studio 2019
environment:
BUILDING_ON_PLATFORM: win
BuildEnvironment: appveyor
Cap_SqlServer_ConnectionStringTemplate: Server=(local)\SQL2014;Database={0};User ID=sa;Password=Password12!
Cap_MySql_ConnectionStringTemplate: Server=localhost;Database={0};Uid=root;Pwd=Password12!;Allow User Variables=True;SslMode=none
Cap_PostgreSql_ConnectionStringTemplate: Server=localhost;Database={0};UserId=postgres;Password=Password12!
services:
- mssql2014
- mysql
- postgresql
- mongodb
build_script:
- ps: ./build.ps1
test: off


+ 3
- 3
build/version.props View File

@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<VersionMajor>2</VersionMajor>
<VersionMinor>6</VersionMinor>
<VersionPatch>1</VersionPatch>
<VersionMajor>3</VersionMajor>
<VersionMinor>0</VersionMinor>
<VersionPatch>0</VersionPatch>
<VersionQuality></VersionQuality>
<VersionPrefix>$(VersionMajor).$(VersionMinor).$(VersionPatch)</VersionPrefix>
</PropertyGroup>


+ 1
- 1
docs/mkdocs.yml View File

@@ -74,7 +74,7 @@ markdown_extensions:
nav:
- Home: index.md
- Documentation:
- Getting Stared:
- Getting Started:
- Quick Start: user-guide/en/getting-started/quick-start.md
- Introduction: user-guide/en/getting-started/introduction.md
- Contributing: user-guide/en/getting-started/contributing.md


+ 0
- 19
samples/Sample.AzureServiceBus.InMemory/Program.cs View File

@@ -1,19 +0,0 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace Sample.AzureServiceBus.InMemory
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}

samples/Sample.AzureServiceBus.InMemory/Controllers/ValuesController.cs → samples/Sample.Kafka.InMemory/Controllers/ValuesController.cs View File

@@ -3,7 +3,7 @@ using System.Threading.Tasks;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Mvc;

namespace Sample.AzureServiceBus.InMemory.Controllers
namespace Sample.Kafka.InMemory.Controllers
{
[Route("api/[controller]")]
public class ValuesController : Controller, ICapSubscribe

+ 20
- 0
samples/Sample.Kafka.InMemory/Program.cs View File

@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Sample.Kafka.InMemory
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

samples/Sample.AzureServiceBus.InMemory/Sample.AzureServiceBus.InMemory.csproj → samples/Sample.Kafka.InMemory/Sample.Kafka.InMemory.csproj View File

@@ -1,17 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<WarningsAsErrors>NU1701</WarningsAsErrors>
<NoWarn>NU1701</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.AzureServiceBus\DotNetCore.CAP.AzureServiceBus.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.InMemoryStorage\DotNetCore.CAP.InMemoryStorage.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.Kafka\DotNetCore.CAP.Kafka.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" />
</ItemGroup>


samples/Sample.AzureServiceBus.InMemory/Startup.cs → samples/Sample.Kafka.InMemory/Startup.cs View File

@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace Sample.AzureServiceBus.InMemory
namespace Sample.Kafka.InMemory
{
public class Startup
{
@@ -10,16 +10,20 @@ namespace Sample.AzureServiceBus.InMemory
services.AddCap(x =>
{
x.UseInMemoryStorage();
x.UseAzureServiceBus("Endpoint=sb://testcap.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<your-key>");
x.UseKafka("192.168.2.120:9093");
x.UseDashboard();
});

services.AddMvc();
services.AddControllers();
}

public void Configure(IApplicationBuilder app)
{
app.UseMvc();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

samples/Sample.AzureServiceBus.InMemory/appsettings.json → samples/Sample.Kafka.InMemory/appsettings.json View File


+ 0
- 19
samples/Sample.Kafka.MySql/Program.cs View File

@@ -1,19 +0,0 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace Sample.Kafka.MySql
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}

samples/Sample.Kafka.MySql/Controllers/ValuesController.cs → samples/Sample.Kafka.PostgreSql/Controllers/ValuesController.cs View File

@@ -4,9 +4,9 @@ using System.Threading.Tasks;
using Dapper;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Mvc;
using MySql.Data.MySqlClient;
using Npgsql;

namespace Sample.Kafka.MySql.Controllers
namespace Sample.Kafka.PostgreSql.Controllers
{
[Route("api/[controller]")]
public class ValuesController : Controller, ICapSubscribe
@@ -21,7 +21,7 @@ namespace Sample.Kafka.MySql.Controllers
[Route("~/without/transaction")]
public async Task<IActionResult> WithoutTransaction()
{
await _capBus.PublishAsync("sample.rabbitmq.mysql", DateTime.Now);
await _capBus.PublishAsync("sample.kafka.postgrsql", DateTime.Now);

return Ok();
}
@@ -29,17 +29,14 @@ namespace Sample.Kafka.MySql.Controllers
[Route("~/adonet/transaction")]
public IActionResult AdonetWithTransaction()
{
using (var connection = new MySqlConnection(""))
using (var connection = new NpgsqlConnection(""))
{
using (var transaction = connection.BeginTransaction(_capBus, autoCommit: false))
{
//your business code
connection.Execute("insert into test(name) values('test')", transaction: (IDbTransaction)transaction.DbTransaction);

for (int i = 0; i < 5; i++)
{
_capBus.Publish("sample.rabbitmq.mysql", DateTime.Now);
}
_capBus.Publish("sample.kafka.postgrsql", DateTime.Now);

transaction.Commit();
}
@@ -49,8 +46,8 @@ namespace Sample.Kafka.MySql.Controllers
}


[CapSubscribe("#.test2")]
public void Test2(int value)
[CapSubscribe("sample.kafka.postgrsql")]
public void Test2(DateTime value)
{
Console.WriteLine("Subscriber output message: " + value);
}

+ 20
- 0
samples/Sample.Kafka.PostgreSql/Program.cs View File

@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Sample.Kafka.PostgreSql
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

samples/Sample.Kafka.MySql/Sample.Kafka.MySql.csproj → samples/Sample.Kafka.PostgreSql/Sample.Kafka.PostgreSql.csproj View File

@@ -1,17 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<WarningsAsErrors>NU1701</WarningsAsErrors>
<NoWarn>NU1701</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.Kafka\DotNetCore.CAP.Kafka.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.MySql\DotNetCore.CAP.MySql.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.PostgreSql\DotNetCore.CAP.PostgreSql.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" />
</ItemGroup>


samples/Sample.Kafka.MySql/Startup.cs → samples/Sample.Kafka.PostgreSql/Startup.cs View File

@@ -1,8 +1,7 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace Sample.Kafka.MySql
namespace Sample.Kafka.PostgreSql
{
public class Startup
{
@@ -10,17 +9,21 @@ namespace Sample.Kafka.MySql
{
services.AddCap(x =>
{
x.UseMySql("Server=localhost;Database=testcap;UserId=root;Password=123123;");
x.UseKafka("localhost:9092");
x.UsePostgreSql("");
x.UseKafka("");
x.UseDashboard();
});

services.AddMvc();
services.AddControllers();
}

public void Configure(IApplicationBuilder app)
{
app.UseMvc();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

samples/Sample.Kafka.MySql/appsettings.json → samples/Sample.Kafka.PostgreSql/appsettings.json View File


+ 2
- 4
samples/Sample.RabbitMQ.MongoDB/Sample.RabbitMQ.MongoDB.csproj View File

@@ -1,14 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.RabbitMQ\DotNetCore.CAP.RabbitMQ.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.MongoDB\DotNetCore.CAP.MongoDB.csproj" />


+ 7
- 11
samples/Sample.RabbitMQ.MongoDB/Startup.cs View File

@@ -1,7 +1,4 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;
@@ -26,17 +23,16 @@ namespace Sample.RabbitMQ.MongoDB
x.UseRabbitMQ("192.168.2.120");
x.UseDashboard();
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddControllers();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
public void Configure(IApplicationBuilder app)
{
if (env.IsDevelopment())
app.UseRouting();
app.UseEndpoints(endpoints =>
{
app.UseDeveloperExceptionPage();
}

app.UseMvc();
endpoints.MapControllers();
});
}
}
}

+ 16
- 1
samples/Sample.RabbitMQ.MySql/AppDbContext.cs View File

@@ -7,11 +7,26 @@ namespace Sample.RabbitMQ.MySql
public int Id { get; set; }

public string Name { get; set; }

public override string ToString()
{
return $"Name:{Name}, Id:{Id}";
}
}
public class Person2
{
public int Id { get; set; }

public string Name { get; set; }

public override string ToString()
{
return $"Name:{Name}, Id:{Id}";
}
}
public class AppDbContext : DbContext
{
public const string ConnectionString = "Server=localhost;Database=testcap;UserId=root;Password=123123;";
public const string ConnectionString = "Server=192.168.2.120;Database=captest;UserId=root;Password=123123;";

public DbSet<Person> Persons { get; set; }



+ 21
- 12
samples/Sample.RabbitMQ.MySql/Controllers/ValuesController.cs View File

@@ -21,7 +21,11 @@ namespace Sample.RabbitMQ.MySql.Controllers
[Route("~/without/transaction")]
public async Task<IActionResult> WithoutTransaction()
{
await _capBus.PublishAsync("sample.rabbitmq.mysql", DateTime.Now);
await _capBus.PublishAsync("sample.rabbitmq.mysql", new Person()
{
Id = 123,
Name = "Bar"
});

return Ok();
}
@@ -31,17 +35,15 @@ namespace Sample.RabbitMQ.MySql.Controllers
{
using (var connection = new MySqlConnection(AppDbContext.ConnectionString))
{
using (var transaction = connection.BeginTransaction(_capBus, autoCommit: false))
using (var transaction = connection.BeginTransaction(_capBus, true))
{
//your business code
connection.Execute("insert into test(name) values('test')", transaction: (IDbTransaction)transaction.DbTransaction);

for (int i = 0; i < 5; i++)
{
_capBus.Publish("sample.rabbitmq.mysql", DateTime.Now);
}

transaction.Commit();
//for (int i = 0; i < 5; i++)
//{
_capBus.Publish("sample.rabbitmq.mysql", DateTime.Now);
//}
}
}

@@ -55,7 +57,7 @@ namespace Sample.RabbitMQ.MySql.Controllers
{
dbContext.Persons.Add(new Person() { Name = "ef.transaction" });

for (int i = 0; i < 5; i++)
for (int i = 0; i < 1; i++)
{
_capBus.Publish("sample.rabbitmq.mysql", DateTime.Now);
}
@@ -68,10 +70,17 @@ namespace Sample.RabbitMQ.MySql.Controllers
}

[NonAction]
[CapSubscribe("#.rabbitmq.mysql")]
public void Subscriber(DateTime time)
[CapSubscribe("sample.rabbitmq.mysql")]
public void Subscriber(DateTime p)
{
Console.WriteLine($@"{DateTime.Now} Subscriber invoked, Info: {p}");
}

[NonAction]
[CapSubscribe("sample.rabbitmq.mysql", Group = "group.test2")]
public void Subscriber2(DateTime p, [FromCap]CapHeader header)
{
Console.WriteLine($@"{DateTime.Now}, Subscriber invoked, Sent time:{time}");
Console.WriteLine($@"{DateTime.Now} Subscriber invoked, Info: {p}");
}
}
}

+ 9
- 7
samples/Sample.RabbitMQ.MySql/Program.cs View File

@@ -1,5 +1,5 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Sample.RabbitMQ.MySql
{
@@ -7,12 +7,14 @@ namespace Sample.RabbitMQ.MySql
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
CreateHostBuilder(args).Build().Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

+ 7
- 6
samples/Sample.RabbitMQ.MySql/Properties/launchSettings.json View File

@@ -1,10 +1,11 @@
{
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:57171/",
"sslPort": 0
"applicationUrl": "http://localhost:49558",
"sslPort": 44332
}
},
"profiles": {
@@ -20,10 +21,10 @@
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "cap",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:57173/"
}
}
}
}
}

+ 4
- 4
samples/Sample.RabbitMQ.MySql/Sample.RabbitMQ.MySql.csproj View File

@@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.4" />
</ItemGroup>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.0-rc1.final" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.MySql\DotNetCore.CAP.MySql.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.RabbitMQ\DotNetCore.CAP.RabbitMQ.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" />


+ 12
- 8
samples/Sample.RabbitMQ.MySql/Startup.cs View File

@@ -1,8 +1,7 @@
using System;
using DotNetCore.CAP.Messages;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Sample.RabbitMQ.MySql
{
@@ -15,21 +14,26 @@ namespace Sample.RabbitMQ.MySql
services.AddCap(x =>
{
x.UseEntityFramework<AppDbContext>();
x.UseRabbitMQ("localhost");
x.UseRabbitMQ("192.168.2.120");
x.UseDashboard();
x.FailedRetryCount = 5;
x.FailedThresholdCallback = (type, name, content) =>
x.FailedThresholdCallback = (type, msg) =>
{
Console.WriteLine($@"A message of type {type} failed after executing {x.FailedRetryCount} several times, requiring manual troubleshooting. Message name: {name}, message body: {content}");
Console.WriteLine(
$@"A message of type {type} failed after executing {x.FailedRetryCount} several times, requiring manual troubleshooting. Message name: {msg.GetName()}");
};
});

services.AddMvc();
services.AddControllers();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

+ 1
- 1
samples/Sample.RabbitMQ.MySql/appsettings.json View File

@@ -2,7 +2,7 @@
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug"
"Default": "Error"
}
}
}

+ 40
- 0
samples/Sample.RabbitMQ.SqlServer/AppDbContext.cs View File

@@ -0,0 +1,40 @@
using Microsoft.EntityFrameworkCore;

namespace Sample.RabbitMQ.SqlServer
{
public class Person
{
public int Id { get; set; }

public string Name { get; set; }

public override string ToString()
{
return $"Name:{Name}, Id:{Id}";
}
}

public class Person2
{
public int Id { get; set; }

public string Name { get; set; }

public override string ToString()
{
return $"Name:{Name}, Id:{Id}";
}
}

public class AppDbContext : DbContext
{
public const string ConnectionString = "Server=192.168.2.120;Database=captest;User Id=sa;Password=P@ssw0rd;";

public DbSet<Person> Persons { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(ConnectionString);
}
}
}

+ 76
- 0
samples/Sample.RabbitMQ.SqlServer/Controllers/ValuesController.cs View File

@@ -0,0 +1,76 @@
using System;
using System.Data;
using System.Threading.Tasks;
using Dapper;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;

namespace Sample.RabbitMQ.SqlServer.Controllers
{
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly ICapPublisher _capBus;

public ValuesController(ICapPublisher capPublisher)
{
_capBus = capPublisher;
}

[Route("~/without/transaction")]
public async Task<IActionResult> WithoutTransaction()
{
await _capBus.PublishAsync("sample.rabbitmq.mysql", new Person()
{
Id = 123,
Name = "Bar"
});

return Ok();
}

[Route("~/adonet/transaction")]
public IActionResult AdonetWithTransaction()
{
using (var connection = new SqlConnection(AppDbContext.ConnectionString))
{
using (var transaction = connection.BeginTransaction(_capBus, true))
{
//your business code
connection.Execute("insert into test(name) values('test')", transaction: transaction);

_capBus.Publish("sample.rabbitmq.mysql", DateTime.Now);
}
}

return Ok();
}

[Route("~/ef/transaction")]
public IActionResult EntityFrameworkWithTransaction([FromServices]AppDbContext dbContext)
{
using (dbContext.Database.BeginTransaction(_capBus, autoCommit: true))
{
dbContext.Persons.Add(new Person() { Name = "ef.transaction" });

_capBus.Publish("sample.rabbitmq.mysql", DateTime.Now);
}
return Ok();
}

[NonAction]
[CapSubscribe("sample.rabbitmq.mysql")]
public void Subscriber(DateTime p)
{
Console.WriteLine($@"{DateTime.Now} Subscriber invoked, Info: {p}");
}

[NonAction]
[CapSubscribe("sample.rabbitmq.mysql", Group = "group.test2")]
public void Subscriber2(DateTime p, [FromCap]CapHeader header)
{
Console.WriteLine($@"{DateTime.Now} Subscriber invoked, Info: {p}");
}
}
}

+ 40
- 0
samples/Sample.RabbitMQ.SqlServer/Migrations/20191205032949_FirstMigration.Designer.cs View File

@@ -0,0 +1,40 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Sample.RabbitMQ.SqlServer;

namespace Sample.RabbitMQ.SqlServer.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20191205032949_FirstMigration")]
partial class FirstMigration
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

modelBuilder.Entity("Sample.RabbitMQ.SqlServer.Person", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

b.Property<string>("Name")
.HasColumnType("nvarchar(max)");

b.HasKey("Id");

b.ToTable("Persons");
});
#pragma warning restore 612, 618
}
}
}

+ 29
- 0
samples/Sample.RabbitMQ.SqlServer/Migrations/20191205032949_FirstMigration.cs View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;

namespace Sample.RabbitMQ.SqlServer.Migrations
{
public partial class FirstMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Persons",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Persons", x => x.Id);
});
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Persons");
}
}
}

+ 38
- 0
samples/Sample.RabbitMQ.SqlServer/Migrations/AppDbContextModelSnapshot.cs View File

@@ -0,0 +1,38 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Sample.RabbitMQ.SqlServer;

namespace Sample.RabbitMQ.SqlServer.Migrations
{
[DbContext(typeof(AppDbContext))]
partial class AppDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

modelBuilder.Entity("Sample.RabbitMQ.SqlServer.Person", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

b.Property<string>("Name")
.HasColumnType("nvarchar(max)");

b.HasKey("Id");

b.ToTable("Persons");
});
#pragma warning restore 612, 618
}
}
}

+ 20
- 0
samples/Sample.RabbitMQ.SqlServer/Program.cs View File

@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Sample.RabbitMQ.SqlServer
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

+ 22
- 0
samples/Sample.RabbitMQ.SqlServer/Sample.RabbitMQ.SqlServer.csproj View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.RabbitMQ\DotNetCore.CAP.RabbitMQ.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.SqlServer\DotNetCore.CAP.SqlServer.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP\DotNetCore.CAP.csproj" />
</ItemGroup>

</Project>

+ 39
- 0
samples/Sample.RabbitMQ.SqlServer/Startup.cs View File

@@ -0,0 +1,39 @@
using System;
using DotNetCore.CAP.Messages;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace Sample.RabbitMQ.SqlServer
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>();

services.AddCap(x =>
{
x.UseEntityFramework<AppDbContext>();
x.UseRabbitMQ("192.168.2.120");
x.UseDashboard();
x.FailedRetryCount = 5;
x.FailedThresholdCallback = (type, msg) =>
{
Console.WriteLine(
$@"A message of type {type} failed after executing {x.FailedRetryCount} several times, requiring manual troubleshooting. Message name: {msg.GetName()}");
};
});

services.AddControllers();
}

public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

+ 8
- 0
samples/Sample.RabbitMQ.SqlServer/appsettings.json View File

@@ -0,0 +1,8 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Error"
}
}
}

+ 1
- 1
src/Directory.Build.props View File

@@ -23,7 +23,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19351-01" PrivateAssets="All"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>

</Project>

+ 8
- 7
src/DotNetCore.CAP.AzureServiceBus/AzureServiceBusConsumerClient.cs View File

@@ -7,10 +7,13 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DotNetCore.CAP.Messages;
using DotNetCore.CAP.Transport;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Management;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Message = Microsoft.Azure.ServiceBus.Message;

namespace DotNetCore.CAP.AzureServiceBus
{
@@ -36,7 +39,7 @@ namespace DotNetCore.CAP.AzureServiceBus
_asbOptions = options.Value ?? throw new ArgumentNullException(nameof(options));
}

public event EventHandler<MessageContext> OnMessageReceived;
public event EventHandler<TransportMessage> OnMessageReceived;

public event EventHandler<LogMessageEventArgs> OnLog;

@@ -160,12 +163,10 @@ namespace DotNetCore.CAP.AzureServiceBus
private Task OnConsumerReceived(Message message, CancellationToken token)
{
_lockToken = message.SystemProperties.LockToken;
var context = new MessageContext
{
Group = _subscriptionName,
Name = message.Label,
Content = Encoding.UTF8.GetString(message.Body)
};

var header = message.UserProperties.ToDictionary(x => x.Key, y => y.Value.ToString());

var context = new TransportMessage(header, message.Body);

OnMessageReceived?.Invoke(null, context);



+ 1
- 0
src/DotNetCore.CAP.AzureServiceBus/AzureServiceBusConsumerClientFactory.cs View File

@@ -1,6 +1,7 @@
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using DotNetCore.CAP.Transport;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;



+ 0
- 1
src/DotNetCore.CAP.AzureServiceBus/CAP.AzureServiceBusOptions.cs View File

@@ -1,7 +1,6 @@
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Primitives;

// ReSharper disable once CheckNamespace


+ 2
- 2
src/DotNetCore.CAP.AzureServiceBus/CAP.AzureServiceBusOptionsExtension.cs View File

@@ -3,6 +3,7 @@

using System;
using DotNetCore.CAP.AzureServiceBus;
using DotNetCore.CAP.Transport;
using Microsoft.Extensions.DependencyInjection;

// ReSharper disable once CheckNamespace
@@ -24,8 +25,7 @@ namespace DotNetCore.CAP
services.Configure(_configure);

services.AddSingleton<IConsumerClientFactory, AzureServiceBusConsumerClientFactory>();
services.AddSingleton<IPublishExecutor, AzureServiceBusPublishMessageSender>();
services.AddSingleton<IPublishMessageSender, AzureServiceBusPublishMessageSender>();
services.AddSingleton<ITransport,AzureServiceBusTransport>();
}
}
}

src/DotNetCore.CAP.AzureServiceBus/IPublishMessageSender.AzureServiceBus.cs → src/DotNetCore.CAP.AzureServiceBus/ITransport.AzureServiceBus.cs View File

@@ -2,18 +2,18 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DotNetCore.CAP.Internal;
using DotNetCore.CAP.Processor.States;
using DotNetCore.CAP.Messages;
using DotNetCore.CAP.Transport;
using Microsoft.Azure.ServiceBus;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace DotNetCore.CAP.AzureServiceBus
{
internal class AzureServiceBusPublishMessageSender : BasePublishMessageSender
internal class AzureServiceBusTransport : ITransport
{
private readonly SemaphoreSlim _connectionLock = new SemaphoreSlim(initialCount: 1, maxCount: 1);

@@ -22,38 +22,37 @@ namespace DotNetCore.CAP.AzureServiceBus

private ITopicClient _topicClient;

public AzureServiceBusPublishMessageSender(
ILogger<AzureServiceBusPublishMessageSender> logger,
IOptions<CapOptions> options,
IOptions<AzureServiceBusOptions> asbOptions,
IStateChanger stateChanger,
IStorageConnection connection)
: base(logger, options, connection, stateChanger)
public AzureServiceBusTransport(
ILogger<AzureServiceBusTransport> logger,
IOptions<AzureServiceBusOptions> asbOptions)
{
_logger = logger;
_asbOptions = asbOptions;
}

protected override string ServersAddress => _asbOptions.Value.ConnectionString;
public string Address => _asbOptions.Value.ConnectionString;

public override async Task<OperateResult> PublishAsync(string keyName, string content)
public async Task<OperateResult> SendAsync(TransportMessage transportMessage)
{
try
{
Connect();

var contentBytes = Encoding.UTF8.GetBytes(content);

var message = new Message
var message = new Microsoft.Azure.ServiceBus.Message
{
MessageId = Guid.NewGuid().ToString(),
Body = contentBytes,
Label = keyName,
MessageId = transportMessage.GetId(),
Body = transportMessage.Body,
Label = transportMessage.GetName()
};

foreach (var header in transportMessage.Headers)
{
message.UserProperties.Add(header.Key, header.Value);
}

await _topicClient.SendAsync(message);

_logger.LogDebug($"Azure Service Bus message [{keyName}] has been published.");
_logger.LogDebug($"Azure Service Bus message [{transportMessage.GetName()}] has been published.");

return OperateResult.Success;
}
@@ -78,7 +77,7 @@ namespace DotNetCore.CAP.AzureServiceBus
{
if (_topicClient == null)
{
_topicClient = new TopicClient(ServersAddress, _asbOptions.Value.TopicPath, RetryPolicy.NoRetry);
_topicClient = new TopicClient(Address, _asbOptions.Value.TopicPath, RetryPolicy.NoRetry);
}
}
finally

+ 128
- 0
src/DotNetCore.CAP.Dashboard/AwaitableInfo.cs View File

@@ -0,0 +1,128 @@
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace Microsoft.Extensions.Internal
{
internal struct AwaitableInfo
{
public Type AwaiterType { get; }
public PropertyInfo AwaiterIsCompletedProperty { get; }
public MethodInfo AwaiterGetResultMethod { get; }
public MethodInfo AwaiterOnCompletedMethod { get; }
public MethodInfo AwaiterUnsafeOnCompletedMethod { get; }
public Type ResultType { get; }
public MethodInfo GetAwaiterMethod { get; }

public AwaitableInfo(
Type awaiterType,
PropertyInfo awaiterIsCompletedProperty,
MethodInfo awaiterGetResultMethod,
MethodInfo awaiterOnCompletedMethod,
MethodInfo awaiterUnsafeOnCompletedMethod,
Type resultType,
MethodInfo getAwaiterMethod)
{
AwaiterType = awaiterType;
AwaiterIsCompletedProperty = awaiterIsCompletedProperty;
AwaiterGetResultMethod = awaiterGetResultMethod;
AwaiterOnCompletedMethod = awaiterOnCompletedMethod;
AwaiterUnsafeOnCompletedMethod = awaiterUnsafeOnCompletedMethod;
ResultType = resultType;
GetAwaiterMethod = getAwaiterMethod;
}

public static bool IsTypeAwaitable(Type type, out AwaitableInfo awaitableInfo)
{
// Based on Roslyn code: http://source.roslyn.io/#Microsoft.CodeAnalysis.Workspaces/Shared/Extensions/ISymbolExtensions.cs,db4d48ba694b9347

// Awaitable must have method matching "object GetAwaiter()"
var getAwaiterMethod = type.GetRuntimeMethods().FirstOrDefault(m =>
m.Name.Equals("GetAwaiter", StringComparison.OrdinalIgnoreCase)
&& m.GetParameters().Length == 0
&& m.ReturnType != null);
if (getAwaiterMethod == null)
{
awaitableInfo = default(AwaitableInfo);
return false;
}

var awaiterType = getAwaiterMethod.ReturnType;

// Awaiter must have property matching "bool IsCompleted { get; }"
var isCompletedProperty = awaiterType.GetRuntimeProperties().FirstOrDefault(p =>
p.Name.Equals("IsCompleted", StringComparison.OrdinalIgnoreCase)
&& p.PropertyType == typeof(bool)
&& p.GetMethod != null);
if (isCompletedProperty == null)
{
awaitableInfo = default(AwaitableInfo);
return false;
}

// Awaiter must implement INotifyCompletion
var awaiterInterfaces = awaiterType.GetInterfaces();
var implementsINotifyCompletion = awaiterInterfaces.Any(t => t == typeof(INotifyCompletion));
if (!implementsINotifyCompletion)
{
awaitableInfo = default(AwaitableInfo);
return false;
}

// INotifyCompletion supplies a method matching "void OnCompleted(Action action)"
var iNotifyCompletionMap = awaiterType
.GetTypeInfo()
.GetRuntimeInterfaceMap(typeof(INotifyCompletion));
var onCompletedMethod = iNotifyCompletionMap.InterfaceMethods.Single(m =>
m.Name.Equals("OnCompleted", StringComparison.OrdinalIgnoreCase)
&& m.ReturnType == typeof(void)
&& m.GetParameters().Length == 1
&& m.GetParameters()[0].ParameterType == typeof(Action));

// Awaiter optionally implements ICriticalNotifyCompletion
var implementsICriticalNotifyCompletion =
awaiterInterfaces.Any(t => t == typeof(ICriticalNotifyCompletion));
MethodInfo unsafeOnCompletedMethod;
if (implementsICriticalNotifyCompletion)
{
// ICriticalNotifyCompletion supplies a method matching "void UnsafeOnCompleted(Action action)"
var iCriticalNotifyCompletionMap = awaiterType
.GetTypeInfo()
.GetRuntimeInterfaceMap(typeof(ICriticalNotifyCompletion));
unsafeOnCompletedMethod = iCriticalNotifyCompletionMap.InterfaceMethods.Single(m =>
m.Name.Equals("UnsafeOnCompleted", StringComparison.OrdinalIgnoreCase)
&& m.ReturnType == typeof(void)
&& m.GetParameters().Length == 1
&& m.GetParameters()[0].ParameterType == typeof(Action));
}
else
{
unsafeOnCompletedMethod = null;
}

// Awaiter must have method matching "void GetResult" or "T GetResult()"
var getResultMethod = awaiterType.GetRuntimeMethods().FirstOrDefault(m =>
m.Name.Equals("GetResult")
&& m.GetParameters().Length == 0);
if (getResultMethod == null)
{
awaitableInfo = default(AwaitableInfo);
return false;
}

awaitableInfo = new AwaitableInfo(
awaiterType,
isCompletedProperty,
getResultMethod,
onCompletedMethod,
unsafeOnCompletedMethod,
getResultMethod.ReturnType,
getAwaiterMethod);
return true;
}
}
}

src/DotNetCore.CAP/Dashboard/BatchCommandDispatcher.cs → src/DotNetCore.CAP.Dashboard/BatchCommandDispatcher.cs View File


src/DotNetCore.CAP/Dashboard/CAP.DashboardMiddleware.cs → src/DotNetCore.CAP.Dashboard/CAP.DashboardMiddleware.cs View File

@@ -6,19 +6,89 @@ using System.Linq;
using System.Net;
using System.Threading.Tasks;
using DotNetCore.CAP.Dashboard;
using DotNetCore.CAP.Dashboard.GatewayProxy;
using DotNetCore.CAP.Dashboard.NodeDiscovery;
using DotNetCore.CAP.Persistence;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

// ReSharper disable once CheckNamespace
namespace DotNetCore.CAP
{
public static class CapBuilderExtension
{
public static IApplicationBuilder UseCapDashboard(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}

CheckRequirement(app);

var provider = app.ApplicationServices;

if (provider.GetService<DashboardOptions>() != null)
{
if (provider.GetService<DiscoveryOptions>() != null)
{
app.UseMiddleware<GatewayProxyMiddleware>();
}

app.UseMiddleware<DashboardMiddleware>();
}

return app;
}

private static void CheckRequirement(IApplicationBuilder app)
{
var marker = app.ApplicationServices.GetService<CapMarkerService>();
if (marker == null)
{
throw new InvalidOperationException(
"AddCap() must be called on the service collection. eg: services.AddCap(...)");
}

var messageQueueMarker = app.ApplicationServices.GetService<CapMessageQueueMakerService>();
if (messageQueueMarker == null)
{
throw new InvalidOperationException(
"You must be config used message queue provider at AddCap() options! eg: services.AddCap(options=>{ options.UseKafka(...) })");
}

var databaseMarker = app.ApplicationServices.GetService<CapStorageMarkerService>();
if (databaseMarker == null)
{
throw new InvalidOperationException(
"You must be config used database provider at AddCap() options! eg: services.AddCap(options=>{ options.UseSqlServer(...) })");
}
}
}

sealed class CapStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
app.UseCapDashboard();

next(app);
};
}
}

public class DashboardMiddleware
{
private readonly RequestDelegate _next;
private readonly DashboardOptions _options;
private readonly RouteCollection _routes;
private readonly IStorage _storage;
private readonly IDataStorage _storage;

public DashboardMiddleware(RequestDelegate next, DashboardOptions options, IStorage storage,
public DashboardMiddleware(RequestDelegate next, DashboardOptions options, IDataStorage storage,
RouteCollection routes)
{
_next = next ?? throw new ArgumentNullException(nameof(next));

src/DotNetCore.CAP/Dashboard/CAP.DashboardOptions.cs → src/DotNetCore.CAP.Dashboard/CAP.DashboardOptions.cs View File


src/DotNetCore.CAP/Dashboard/CAP.DashboardOptionsExtensions.cs → src/DotNetCore.CAP.Dashboard/CAP.DashboardOptionsExtensions.cs View File

@@ -6,6 +6,7 @@ using DotNetCore.CAP;
using DotNetCore.CAP.Dashboard;
using DotNetCore.CAP.Dashboard.GatewayProxy;
using DotNetCore.CAP.Dashboard.GatewayProxy.Requester;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace DotNetCore.CAP
@@ -23,11 +24,13 @@ namespace DotNetCore.CAP
{
var dashboardOptions = new DashboardOptions();
_options?.Invoke(dashboardOptions);
services.AddTransient<IStartupFilter, CapStartupFilter>();
services.AddSingleton(dashboardOptions);
services.AddSingleton(DashboardRoutes.Routes);
services.AddSingleton<IHttpRequester, HttpClientHttpRequester>();
services.AddSingleton<IHttpClientCache, MemoryHttpClientCache>();
services.AddSingleton<IRequestMapper, RequestMapper>();

}
}
}

src/DotNetCore.CAP/Internal/CapCache.cs → src/DotNetCore.CAP.Dashboard/CapCache.cs View File

@@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace DotNetCore.CAP.Internal
namespace DotNetCore.CAP.Dashboard
{
#region Cache<T> class


+ 44
- 0
src/DotNetCore.CAP.Dashboard/CoercedAwaitableInfo.cs View File

@@ -0,0 +1,44 @@
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Linq.Expressions;
using Microsoft.Extensions.Internal;

namespace DotNetCore.CAP.Dashboard
{
internal struct CoercedAwaitableInfo
{
public AwaitableInfo AwaitableInfo { get; }
public Expression CoercerExpression { get; }
public Type CoercerResultType { get; }
public bool RequiresCoercion => CoercerExpression != null;

public CoercedAwaitableInfo(AwaitableInfo awaitableInfo)
{
AwaitableInfo = awaitableInfo;
CoercerExpression = null;
CoercerResultType = null;
}

public CoercedAwaitableInfo(Expression coercerExpression, Type coercerResultType,
AwaitableInfo coercedAwaitableInfo)
{
CoercerExpression = coercerExpression;
CoercerResultType = coercerResultType;
AwaitableInfo = coercedAwaitableInfo;
}

public static bool IsTypeAwaitable(Type type, out CoercedAwaitableInfo info)
{
if (AwaitableInfo.IsTypeAwaitable(type, out var directlyAwaitableInfo))
{
info = new CoercedAwaitableInfo(directlyAwaitableInfo);
return true;
}

info = default(CoercedAwaitableInfo);
return false;
}
}
}

src/DotNetCore.CAP/Dashboard/CombinedResourceDispatcher.cs → src/DotNetCore.CAP.Dashboard/CombinedResourceDispatcher.cs View File

@@ -27,10 +27,10 @@ namespace DotNetCore.CAP.Dashboard
{
foreach (var resourceName in _resourceNames)
{
await WriteResource(
response,
_assembly,
$"{_baseNamespace}.{resourceName}").ConfigureAwait(false);
await WriteResource(
response,
_assembly,
$"{_baseNamespace}.{resourceName}");
}
}
}

src/DotNetCore.CAP/Dashboard/CommandDispatcher.cs → src/DotNetCore.CAP.Dashboard/CommandDispatcher.cs View File


src/DotNetCore.CAP/Dashboard/Content/css/bootstrap.min.css → src/DotNetCore.CAP.Dashboard/Content/css/bootstrap.min.css View File


src/DotNetCore.CAP/Dashboard/Content/css/cap.css → src/DotNetCore.CAP.Dashboard/Content/css/cap.css View File


src/DotNetCore.CAP/Dashboard/Content/css/jsonview.min.css → src/DotNetCore.CAP.Dashboard/Content/css/jsonview.min.css View File


src/DotNetCore.CAP/Dashboard/Content/css/rickshaw.min.css → src/DotNetCore.CAP.Dashboard/Content/css/rickshaw.min.css View File


src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.eot → src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.eot View File


src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.svg → src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.svg View File


src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.ttf → src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.ttf View File


src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.woff → src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.woff View File


src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.woff2 → src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.woff2 View File


src/DotNetCore.CAP/Dashboard/Content/js/bootstrap.min.js → src/DotNetCore.CAP.Dashboard/Content/js/bootstrap.min.js View File


src/DotNetCore.CAP/Dashboard/Content/js/cap.js → src/DotNetCore.CAP.Dashboard/Content/js/cap.js View File


src/DotNetCore.CAP/Dashboard/Content/js/d3.layout.min.js → src/DotNetCore.CAP.Dashboard/Content/js/d3.layout.min.js View File


src/DotNetCore.CAP/Dashboard/Content/js/d3.min.js → src/DotNetCore.CAP.Dashboard/Content/js/d3.min.js View File


src/DotNetCore.CAP/Dashboard/Content/js/jquery-2.1.4.min.js → src/DotNetCore.CAP.Dashboard/Content/js/jquery-2.1.4.min.js View File


src/DotNetCore.CAP/Dashboard/Content/js/jsonview.min.js → src/DotNetCore.CAP.Dashboard/Content/js/jsonview.min.js View File


src/DotNetCore.CAP/Dashboard/Content/js/moment-with-locales.min.js → src/DotNetCore.CAP.Dashboard/Content/js/moment-with-locales.min.js View File


src/DotNetCore.CAP/Dashboard/Content/js/moment.min.js → src/DotNetCore.CAP.Dashboard/Content/js/moment.min.js View File


src/DotNetCore.CAP/Dashboard/Content/js/rickshaw.min.js → src/DotNetCore.CAP.Dashboard/Content/js/rickshaw.min.js View File


src/DotNetCore.CAP/Dashboard/Content/resx/Strings.Designer.cs → src/DotNetCore.CAP.Dashboard/Content/resx/Strings.Designer.cs View File

@@ -19,7 +19,7 @@ namespace DotNetCore.CAP.Dashboard.Resources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Strings {

src/DotNetCore.CAP/Dashboard/Content/resx/Strings.resx → src/DotNetCore.CAP.Dashboard/Content/resx/Strings.resx View File


src/DotNetCore.CAP/Dashboard/Content/resx/Strings.zh.resx → src/DotNetCore.CAP.Dashboard/Content/resx/Strings.zh.resx View File


src/DotNetCore.CAP/Dashboard/DashboardContext.cs → src/DotNetCore.CAP.Dashboard/DashboardContext.cs View File

@@ -3,13 +3,14 @@

using System;
using System.Text.RegularExpressions;
using DotNetCore.CAP.Persistence;
using Microsoft.AspNetCore.Http;

namespace DotNetCore.CAP.Dashboard
{
public abstract class DashboardContext
{
protected DashboardContext(IStorage storage, DashboardOptions options)
protected DashboardContext(IDataStorage storage, DashboardOptions options)
{
if (storage == null)
{
@@ -25,7 +26,7 @@ namespace DotNetCore.CAP.Dashboard
Options = options;
}

public IStorage Storage { get; }
public IDataStorage Storage { get; }

public DashboardOptions Options { get; }

@@ -41,7 +42,7 @@ namespace DotNetCore.CAP.Dashboard
public sealed class CapDashboardContext : DashboardContext
{
public CapDashboardContext(
IStorage storage,
IDataStorage storage,
DashboardOptions options,
HttpContext httpContext)
: base(storage, options)

src/DotNetCore.CAP/Dashboard/DashboardMetric.cs → src/DotNetCore.CAP.Dashboard/DashboardMetric.cs View File


src/DotNetCore.CAP/Dashboard/DashboardMetrics.cs → src/DotNetCore.CAP.Dashboard/DashboardMetrics.cs View File


src/DotNetCore.CAP/Dashboard/DashboardRequest.cs → src/DotNetCore.CAP.Dashboard/DashboardRequest.cs View File


src/DotNetCore.CAP/Dashboard/DashboardResponse.cs → src/DotNetCore.CAP.Dashboard/DashboardResponse.cs View File


src/DotNetCore.CAP/Dashboard/DashboardRoutes.cs → src/DotNetCore.CAP.Dashboard/DashboardRoutes.cs View File

@@ -3,6 +3,8 @@

using System.Reflection;
using DotNetCore.CAP.Dashboard.Pages;
using DotNetCore.CAP.Internal;
using DotNetCore.CAP.Transport;
using Microsoft.Extensions.DependencyInjection;

namespace DotNetCore.CAP.Dashboard
@@ -83,14 +85,14 @@ namespace DotNetCore.CAP.Dashboard
Routes.AddJsonResult("/published/message/(?<Id>.+)", x =>
{
var id = long.Parse(x.UriMatch.Groups["Id"].Value);
var message = x.Storage.GetConnection().GetPublishedMessageAsync(id)
var message = x.Storage.GetMonitoringApi().GetPublishedMessageAsync(id)
.GetAwaiter().GetResult();
return message.Content;
});
Routes.AddJsonResult("/received/message/(?<Id>.+)", x =>
{
var id = long.Parse(x.UriMatch.Groups["Id"].Value);
var message = x.Storage.GetConnection().GetReceivedMessageAsync(id)
var message = x.Storage.GetMonitoringApi().GetReceivedMessageAsync(id)
.GetAwaiter().GetResult();
return message.Content;
});
@@ -99,7 +101,7 @@ namespace DotNetCore.CAP.Dashboard
"/published/requeue",
(client, messageId) =>
{
var msg = client.Storage.GetConnection().GetPublishedMessageAsync(messageId)
var msg = client.Storage.GetMonitoringApi().GetPublishedMessageAsync(messageId)
.GetAwaiter().GetResult();
client.RequestServices.GetService<IDispatcher>().EnqueueToPublish(msg);
});
@@ -107,9 +109,9 @@ namespace DotNetCore.CAP.Dashboard
"/received/requeue",
(client, messageId) =>
{
var msg = client.Storage.GetConnection().GetReceivedMessageAsync(messageId)
var msg = client.Storage.GetMonitoringApi().GetReceivedMessageAsync(messageId)
.GetAwaiter().GetResult();
client.RequestServices.GetService<IDispatcher>().EnqueueToExecute(msg);
client.RequestServices.GetService<ISubscribeDispatcher>().DispatchAsync(msg);
});

Routes.AddRazorPage(

+ 239
- 0
src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj View File

@@ -0,0 +1,239 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<NoWarn>1591</NoWarn>
</PropertyGroup>

<PropertyGroup>
<MSBuildCurrentFullPath>C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe</MSBuildCurrentFullPath>
<RazorProjectFile>Razor.build</RazorProjectFile>
<InnerTargets>GenerateRazorClasses;Build</InnerTargets>
</PropertyGroup>

<Target Name="GenerateRazorClasses">
<Exec Command="&quot;$(MSBuildCurrentFullPath)&quot; $(RazorProjectFile) /v:quiet /nologo" Condition="Exists('$(MSBuildCurrentFullPath)')" />
<Warning Text="Classes for Razor files (*.cshtml) weren't re-generated: couldn't find the '$(MSBuildCurrentFullPath)' file" Condition="!Exists('$(MSBuildCurrentFullPath)')" />
</Target>

<ItemGroup>
<EmbeddedResource Include="Content\css\bootstrap.min.css" />
<EmbeddedResource Include="Content\css\cap.css" />
<EmbeddedResource Include="Content\css\jsonview.min.css" />
<EmbeddedResource Include="Content\css\rickshaw.min.css" />
<EmbeddedResource Include="Content\fonts\glyphicons-halflings-regular.eot" />
<EmbeddedResource Include="Content\fonts\glyphicons-halflings-regular.svg" />
<EmbeddedResource Include="Content\fonts\glyphicons-halflings-regular.ttf" />
<EmbeddedResource Include="Content\fonts\glyphicons-halflings-regular.woff" />
<EmbeddedResource Include="Content\fonts\glyphicons-halflings-regular.woff2" />
<EmbeddedResource Include="Content\js\bootstrap.min.js" />
<EmbeddedResource Include="Content\js\cap.js" />
<EmbeddedResource Include="Content\js\d3.layout.min.js" />
<EmbeddedResource Include="Content\js\d3.min.js" />
<EmbeddedResource Include="Content\js\jquery-2.1.4.min.js" />
<EmbeddedResource Include="Content\js\jsonview.min.js" />
<EmbeddedResource Include="Content\js\moment-with-locales.min.js" />
<EmbeddedResource Include="Content\js\moment.min.js" />
<EmbeddedResource Include="Content\js\rickshaw.min.js" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Consul" Version="0.7.2.6" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\DotNetCore.CAP\DotNetCore.CAP.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Update="Content\resx\Strings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
<Compile Update="Pages\_BlockMetric.generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>_BlockMetric.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\_SidebarMenu.generated.cs">
<DependentUpon>_SidebarMenu.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\SidebarMenu.cs">
<DependentUpon>_SidebarMenu.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\ReceivedPage.generated.cs">
<DependentUpon>ReceivedPage.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\ReceivedPage.cs">
<DependentUpon>ReceivedPage.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\BlockMetric.cs">
<DependentUpon>_BlockMetric.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\Breadcrumbs.cs">
<DependentUpon>_Breadcrumbs.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\_Breadcrumbs.generated.cs">
<DependentUpon>_Breadcrumbs.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\_Paginator.generated.cs">
<DependentUpon>_Paginator.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\_Paginator.cs">
<DependentUpon>_Paginator.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\_PerPageSelector.cs">
<DependentUpon>_PerPageSelector.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\_PerPageSelector.generated.cs">
<DependentUpon>_PerPageSelector.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\PublishedPage.cs">
<DependentUpon>PublishedPage.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\PublishedPage*.cs">
<DependentUpon>PublishedPage.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\LayoutPage.*.cs">
<DependentUpon>LayoutPage.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\LayoutPage.cs">
<DependentUpon>LayoutPage.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\InlineMetric.cs">
<DependentUpon>_InlineMetric.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\LayoutPage.generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>LayoutPage.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\PublishedPage.generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>PublishedPage.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\_InlineMetric.generated.cs">
<DependentUpon>_InlineMetric.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\_Navigation.generated.cs">
<DependentUpon>_Navigation.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\HomePage.generated.cs">
<DependentUpon>HomePage.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\HomePage.cs">
<DependentUpon>HomePage.cshtml</DependentUpon>
</Compile>
<Compile Update="Pages\SubscriberPage.generated.cs">
<DependentUpon>SubscriberPage.cshtml</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
<Compile Update="Pages\NodePage*.cs">
<DependentUpon>NodePage.cshtml</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<Compile Update="Pages\NodePage.generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>NodePage.cshtml</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Content\resx\Strings.resx">
<CustomToolNamespace>DotNetCore.CAP.Dashboard.Resources</CustomToolNamespace>
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Content\resx\Strings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<CustomToolNamespace>DotNetCore.CAP.Dashboard.Resources</CustomToolNamespace>
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<None Update="Pages\HomePage.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>HomePage.generated.cs</LastGenOutput>
</None>
<None Update="Pages\LayoutPage.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>LayoutPage.generated.cs</LastGenOutput>
</None>
<None Update="Pages\NodePage.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>NodePage.generated.cs</LastGenOutput>
</None>
<None Update="Pages\PublishedPage.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>PublishedPage.generated.cs</LastGenOutput>
</None>
<None Update="Pages\ReceivedPage.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>ReceivedPage.generated.cs</LastGenOutput>
</None>
<None Update="Pages\SubscriberPage.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>SubscriberPage.generated.cs</LastGenOutput>
</None>
<None Update="Pages\_BlockMetric.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>_BlockMetric.generated.cs</LastGenOutput>
</None>
<None Update="Pages\_Breadcrumbs.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>_Breadcrumbs.generated.cs</LastGenOutput>
</None>
<None Update="Pages\_InlineMetric.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>_InlineMetric.generated.cs</LastGenOutput>
</None>
<None Update="Pages\_Navigation.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>_Navigation.generated.cs</LastGenOutput>
</None>
<None Update="Pages\_Paginator.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>_Paginator.generated.cs</LastGenOutput>
</None>
<None Update="Pages\_PerPageSelector.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>_PerPageSelector.generated.cs</LastGenOutput>
</None>
<None Update="Pages\_SidebarMenu.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>_SidebarMenu.generated.cs</LastGenOutput>
</None>
</ItemGroup>

</Project>

src/DotNetCore.CAP/Dashboard/EmbeddedResourceDispatcher.cs → src/DotNetCore.CAP.Dashboard/EmbeddedResourceDispatcher.cs View File

@@ -35,8 +35,7 @@ namespace DotNetCore.CAP.Dashboard
context.Response.ContentType = _contentType;
context.Response.SetExpire(DateTimeOffset.Now.AddYears(1));

await WriteResponse(context.Response).ConfigureAwait(false);

await WriteResponse(context.Response);
}

protected virtual Task WriteResponse(DashboardResponse response)
@@ -53,8 +52,7 @@ namespace DotNetCore.CAP.Dashboard
throw new ArgumentException(
$@"Resource with name {resourceName} not found in assembly {assembly}.");
}

await inputStream.CopyToAsync(response.Body).ConfigureAwait(false);
await inputStream.CopyToAsync(response.Body);
}
}
}

src/DotNetCore.CAP/Dashboard/GatewayProxy/DownstreamUrl.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/DownstreamUrl.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/GatewayProxyMiddleware.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/GatewayProxyMiddleware.cs View File

@@ -9,7 +9,7 @@ using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using DotNetCore.CAP.Dashboard.GatewayProxy.Requester;
using DotNetCore.CAP.NodeDiscovery;
using DotNetCore.CAP.Dashboard.NodeDiscovery;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;

src/DotNetCore.CAP/Dashboard/GatewayProxy/IRequestMapper.Default.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/IRequestMapper.Default.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/IRequestMapper.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/IRequestMapper.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/HttpClientBuilder.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/HttpClientBuilder.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/HttpClientHttpRequester.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/HttpClientHttpRequester.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClient.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClient.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClientBuilder.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClientBuilder.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClientCache.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClientCache.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpRequester.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpRequester.cs View File


src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/MemoryHttpClientCache.cs → src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/MemoryHttpClientCache.cs View File


src/DotNetCore.CAP/Dashboard/HtmlHelper.cs → src/DotNetCore.CAP.Dashboard/HtmlHelper.cs View File

@@ -10,8 +10,8 @@ using System.Text;
using System.Text.RegularExpressions;
using DotNetCore.CAP.Dashboard.Pages;
using DotNetCore.CAP.Dashboard.Resources;
using DotNetCore.CAP.Infrastructure;
using DotNetCore.CAP.Models;
using DotNetCore.CAP.Internal;
using DotNetCore.CAP.Messages;
using Microsoft.Extensions.Internal;

namespace DotNetCore.CAP.Dashboard

src/DotNetCore.CAP/Dashboard/IDashboardAuthorizationFilter.cs → src/DotNetCore.CAP.Dashboard/IDashboardAuthorizationFilter.cs View File


src/DotNetCore.CAP/Dashboard/IDashboardDispatcher.cs → src/DotNetCore.CAP.Dashboard/IDashboardDispatcher.cs View File


src/DotNetCore.CAP/Dashboard/JsonDispatcher.cs → src/DotNetCore.CAP.Dashboard/JsonDispatcher.cs View File

@@ -37,7 +37,7 @@ namespace DotNetCore.CAP.Dashboard
Converters = new JsonConverter[]
{
new StringEnumConverter
{
{
NamingStrategy = new CamelCaseNamingStrategy()
}
}

src/DotNetCore.CAP/Dashboard/JsonStats.cs → src/DotNetCore.CAP.Dashboard/JsonStats.cs View File

@@ -46,7 +46,7 @@ namespace DotNetCore.CAP.Dashboard

private class StubPage : RazorPage
{
protected override void Execute()
public override void Execute()
{
}
}

src/DotNetCore.CAP/Dashboard/LocalRequestsOnlyAuthorizationFilter.cs → src/DotNetCore.CAP.Dashboard/LocalRequestsOnlyAuthorizationFilter.cs View File

@@ -2,42 +2,40 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Threading.Tasks;
using DotNetCore.CAP.Infrastructure;
using DotNetCore.CAP.Internal;

namespace DotNetCore.CAP.Dashboard
{
public class LocalRequestsOnlyAuthorizationFilter : IDashboardAuthorizationFilter
{
#pragma warning disable 1998
public async Task<bool> AuthorizeAsync(DashboardContext context)
#pragma warning restore 1998
public Task<bool> AuthorizeAsync(DashboardContext context)
{
var ipAddress = context.Request.RemoteIpAddress;
// if unknown, assume not local
if (string.IsNullOrEmpty(ipAddress))
{
return false;
return Task.FromResult(false);
}

// check if localhost
if (ipAddress == "127.0.0.1" || ipAddress == "0.0.0.1")
{
return true;
return Task.FromResult(true);
}

// compare with local address
if (ipAddress == context.Request.LocalIpAddress)
{
return true;
return Task.FromResult(true);
}

// check if private ip
if (Helper.IsInnerIP(ipAddress))
{
return true;
return Task.FromResult(true);
}

return false;
return Task.FromResult(false);
}
}
}

src/DotNetCore.CAP/Dashboard/MenuItem.cs → src/DotNetCore.CAP.Dashboard/MenuItem.cs View File


src/DotNetCore.CAP/Dashboard/MessageHistoryRenderer.cs → src/DotNetCore.CAP.Dashboard/MessageHistoryRenderer.cs View File

@@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Text;
using DotNetCore.CAP.Infrastructure;
using DotNetCore.CAP.Internal;

namespace DotNetCore.CAP.Dashboard
{
@@ -24,16 +24,16 @@ namespace DotNetCore.CAP.Dashboard
[SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
static MessageHistoryRenderer()
{
Register(StatusName.Succeeded, SucceededRenderer);
Register(StatusName.Failed, FailedRenderer);
Register(nameof(StatusName.Succeeded), SucceededRenderer);
Register(nameof(StatusName.Failed), FailedRenderer);

BackgroundStateColors.Add(StatusName.Succeeded, "#EDF7ED");
BackgroundStateColors.Add(StatusName.Failed, "#FAEBEA");
BackgroundStateColors.Add(StatusName.Scheduled, "#E0F3F8");
BackgroundStateColors.Add(nameof(StatusName.Succeeded), "#EDF7ED");
BackgroundStateColors.Add(nameof(StatusName.Failed), "#FAEBEA");
BackgroundStateColors.Add(nameof(StatusName.Scheduled), "#E0F3F8");

ForegroundStateColors.Add(StatusName.Succeeded, "#5cb85c");
ForegroundStateColors.Add(StatusName.Failed, "#d9534f");
ForegroundStateColors.Add(StatusName.Scheduled, "#5bc0de");
ForegroundStateColors.Add(nameof(StatusName.Succeeded), "#5cb85c");
ForegroundStateColors.Add(nameof(StatusName.Failed), "#d9534f");
ForegroundStateColors.Add(nameof(StatusName.Scheduled), "#5bc0de");
}

public static void AddBackgroundStateColor(string stateName, string color)

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save