From 5d1c1bfb0872e343b2ecd4d65e6e4961dca56dda Mon Sep 17 00:00:00 2001 From: Savorboard Date: Thu, 12 Sep 2019 13:52:47 +0800 Subject: [PATCH] Architectural refactoring --- CAP.sln | 7 + .../Controllers/ValuesController.cs | 12 +- samples/Sample.RabbitMQ.MySql/Program.cs | 1 + .../Properties/launchSettings.json | 2 +- samples/Sample.RabbitMQ.MySql/Startup.cs | 5 +- .../Sample.RabbitMQ.MySql/appsettings.json | 2 +- .../CAP.AzureServiceBusOptionsExtension.cs | 2 +- .../BatchCommandDispatcher.cs | 0 .../CAP.DashboardMiddleware.cs | 0 .../CAP.DashboardOptions.cs | 0 .../CAP.DashboardOptionsExtensions.cs | 0 .../CombinedResourceDispatcher.cs | 0 .../CommandDispatcher.cs | 0 .../Content/css/bootstrap.min.css | 0 .../Content/css/cap.css | 0 .../Content/css/jsonview.min.css | 0 .../Content/css/rickshaw.min.css | 0 .../fonts/glyphicons-halflings-regular.eot | Bin .../fonts/glyphicons-halflings-regular.svg | 0 .../fonts/glyphicons-halflings-regular.ttf | Bin .../fonts/glyphicons-halflings-regular.woff | Bin .../fonts/glyphicons-halflings-regular.woff2 | Bin .../Content/js/bootstrap.min.js | 0 .../Content/js/cap.js | 0 .../Content/js/d3.layout.min.js | 0 .../Content/js/d3.min.js | 0 .../Content/js/jquery-2.1.4.min.js | 0 .../Content/js/jsonview.min.js | 0 .../Content/js/moment-with-locales.min.js | 0 .../Content/js/moment.min.js | 0 .../Content/js/rickshaw.min.js | 0 .../Content/resx/Strings.Designer.cs | 2 +- .../Content/resx/Strings.resx | 0 .../Content/resx/Strings.zh.resx | 0 .../DashboardContext.cs | 0 .../DashboardMetric.cs | 0 .../DashboardMetrics.cs | 0 .../DashboardRequest.cs | 0 .../DashboardResponse.cs | 0 .../DashboardRoutes.cs | 0 .../DotNetCore.CAP.Dashboard.csproj | 125 ++++++ .../EmbeddedResourceDispatcher.cs | 0 .../GatewayProxy/DownstreamUrl.cs | 0 .../GatewayProxy/GatewayProxyMiddleware.cs | 0 .../GatewayProxy/IRequestMapper.Default.cs | 0 .../GatewayProxy/IRequestMapper.cs | 0 .../Requester/HttpClientBuilder.cs | 0 .../Requester/HttpClientHttpRequester.cs | 0 .../GatewayProxy/Requester/IHttpClient.cs | 0 .../Requester/IHttpClientBuilder.cs | 0 .../Requester/IHttpClientCache.cs | 0 .../GatewayProxy/Requester/IHttpRequester.cs | 0 .../Requester/MemoryHttpClientCache.cs | 0 .../HtmlHelper.cs | 2 +- .../IDashboardAuthorizationFilter.cs | 0 .../IDashboardDispatcher.cs | 0 .../IMonitoringApi.cs | 2 +- .../JsonDispatcher.cs | 0 .../JsonStats.cs | 0 .../LocalRequestsOnlyAuthorizationFilter.cs | 0 .../MenuItem.cs | 0 .../MessageHistoryRenderer.cs | 0 .../MessagesSidebarMenu.cs | 0 .../Metric.cs | 0 .../Monitoring/MessageDto.cs | 0 .../Monitoring/MessageQueryDto.cs | 2 +- .../Monitoring/ServerDto.cs | 0 .../Monitoring/StatisticsDto.cs | 0 .../NavigationMenu.cs | 0 .../NonEscapedString.cs | 0 .../Pager.cs | 0 .../Pages/BlockMetric.cs | 0 .../Pages/Breadcrumbs.cs | 0 .../Pages/HomePage.cs | 0 .../Pages/HomePage.cshtml | 2 +- .../Pages/HomePage.generated.cs | 6 +- .../Pages/InlineMetric.cs | 0 .../Pages/LayoutPage.cs | 0 .../Pages/LayoutPage.cshtml | 0 .../Pages/LayoutPage.generated.cs | 0 .../Pages/NodePage.cs | 0 .../Pages/NodePage.cshtml | 0 .../Pages/NodePage.generated.cs | 0 .../Pages/PublishedPage.cs | 0 .../Pages/PublishedPage.cshtml | 2 +- .../Pages/PublishedPage.generated.cs | 5 +- .../Pages/ReceivedPage.cs | 0 .../Pages/ReceivedPage.cshtml | 2 +- .../Pages/ReceivedPage.generated.cs | 5 +- .../Pages/SidebarMenu.cs | 0 .../Pages/SubscriberPage.cshtml | 0 .../Pages/SubscriberPage.generated.cs | 0 .../Pages/_BlockMetric.cshtml | 0 .../Pages/_BlockMetric.generated.cs | 0 .../Pages/_Breadcrumbs.cshtml | 0 .../Pages/_Breadcrumbs.generated.cs | 0 .../Pages/_InlineMetric.cshtml | 0 .../Pages/_InlineMetric.generated.cs | 0 .../Pages/_Navigation.cshtml | 0 .../Pages/_Navigation.generated.cs | 0 .../Pages/_Paginator.cs | 0 .../Pages/_Paginator.cshtml | 0 .../Pages/_Paginator.generated.cs | 0 .../Pages/_PerPageSelector.cs | 0 .../Pages/_PerPageSelector.cshtml | 0 .../Pages/_PerPageSelector.generated.cs | 0 .../Pages/_SidebarMenu.cshtml | 0 .../Pages/_SidebarMenu.generated.cs | 0 .../RazorPage.cs | 0 .../RazorPageDispatcher.cs | 0 .../RouteCollection.cs | 0 .../RouteCollectionExtensions.cs | 0 .../TimelineCounter.cs | 0 .../UrlHelper.cs | 0 .../ICapPublisher.InMemory.cs | 2 +- .../IMonitoringApi.InMemory.cs | 2 +- .../IStorageConnection.InMemory.cs | 2 +- .../IStorageTransaction.InMemory.cs | 2 +- .../CAP.KafkaCapOptionsExtension.cs | 2 +- .../ICapPublisher.MongoDB.cs | 2 +- .../IMonitoringApi.MongoDB.cs | 2 +- .../IStorageConnection.MongoDB.cs | 2 +- .../IStorageTransaction.MongoDB.cs | 2 +- src/DotNetCore.CAP.MongoDB/StorageMessage.cs | 2 +- .../CAP.MySqlCapOptionsExtension.cs | 8 +- .../ICapPublisher.MySql.cs | 66 --- .../ICapTransaction.MySql.cs | 1 - .../ICollectProcessor.MySql.cs | 61 --- .../IMonitoringApi.MySql.cs | 425 ++++++++++-------- src/DotNetCore.CAP.MySql/IStorage.MySql.cs | 62 +-- .../IStorageConnection.MySql.cs | 116 ----- .../IStorageTransaction.MySql.cs | 63 --- src/DotNetCore.CAP.MySql/MySqlDataStorage.cs | 215 +++++++++ .../ICapPublisher.PostgreSql.cs | 2 +- .../IMonitoringApi.PostgreSql.cs | 2 +- .../IStorageConnection.PostgreSql.cs | 2 +- .../IStorageTransaction.PostgreSql.cs | 2 +- .../CAP.RabbitMQCapOptionsExtension.cs | 4 +- .../IPublishMessageSender.RabbitMQ.cs | 35 +- .../RabbitMQConsumerClient.cs | 22 +- .../Diagnostics/DiagnosticObserver.cs | 2 +- .../DiagnosticProcessorObserver.cs | 2 +- .../ICapPublisher.SqlServer.cs | 2 +- .../ICapTransaction.SqlServer.cs | 2 +- .../IMonitoringApi.SqlServer.cs | 2 +- .../IStorageConnection.SqlServer.cs | 2 +- .../IStorageTransaction.SqlServer.cs | 2 +- .../Abstractions/CapPublisher.cs | 117 +++++ .../Abstractions/CapPublisherBase.cs | 128 ------ .../Abstractions/IContentSerializer.cs | 2 +- .../CAP.AppBuilderExtensions.cs | 60 ++- src/DotNetCore.CAP/CAP.Options.cs | 5 +- .../CAP.ServiceCollectionExtensions.cs | 7 +- .../DiagnosticListenerExtensions.cs | 283 ++++++------ .../Diagnostics/EventData.Broker.Consume.cs | 16 +- .../EventData.Broker.ConsumeEnd.cs | 7 +- .../EventData.Broker.ConsumeError.cs | 17 +- .../Diagnostics/EventData.Broker.Publish.cs | 5 +- .../EventData.Broker.PublishEnd.cs | 6 +- .../EventData.Broker.PublishError.cs | 6 +- .../Diagnostics/EventData.Broker.cs | 14 +- .../Diagnostics/EventData.SubscriberInvoke.cs | 5 +- src/DotNetCore.CAP/DotNetCore.CAP.csproj | 104 +---- src/DotNetCore.CAP/IBootstrapper.Default.cs | 5 +- src/DotNetCore.CAP/ICallbackPublisher.cs | 2 +- src/DotNetCore.CAP/ICapPublisher.cs | 6 +- src/DotNetCore.CAP/ICapTransaction.Base.cs | 9 +- src/DotNetCore.CAP/IConsumerClient.cs | 3 +- .../IConsumerRegister.Default.cs | 115 ++--- src/DotNetCore.CAP/IDispatcher.cs | 7 +- src/DotNetCore.CAP/IPublishExecutor.cs | 21 - .../IPublishMessageSender.Base.cs | 198 -------- src/DotNetCore.CAP/IPublishMessageSender.cs | 13 - src/DotNetCore.CAP/IStorage.cs | 30 -- src/DotNetCore.CAP/IStorageConnection.cs | 6 +- src/DotNetCore.CAP/IStorageTransaction.cs | 22 - .../ISubscribeExecutor.Default.cs | 86 ++-- src/DotNetCore.CAP/ISubscriberExecutor.cs | 4 +- .../Infrastructure/StatusName.cs | 20 +- .../Internal/ConsumerContext.cs | 5 +- .../Internal/ConsumerInvokerFactory.cs | 14 +- .../ICallbackMessageSender.Default.cs | 71 --- .../Internal/IConsumerInvoker.Default.cs | 60 +-- .../Internal/IMessagePacker.Default.cs | 2 +- .../Internal/IMessageSender.Default.cs | 184 ++++++++ ...backMessageSender.cs => IMessageSender.cs} | 5 +- .../Internal/LoggerExtensions.cs | 8 +- src/DotNetCore.CAP/MessageContext.cs | 33 -- .../{Models => Messages}/CapMessageDto.cs | 3 +- src/DotNetCore.CAP/Messages/Headers.cs | 30 ++ src/DotNetCore.CAP/Messages/Message.cs | 56 +++ .../{Models => Messages}/MessageType.cs | 2 +- .../Messages/TransportMessage.cs | 32 ++ .../Models/CapReceivedMessage.cs | 56 --- .../Persistence/CapPublishedMessage.cs | 25 ++ .../CapReceivedMessage.cs} | 12 +- .../Persistence/IDashboardQuerying.cs | 26 ++ .../Persistence/IDataStorage.cs | 52 +++ .../Persistence/IStorageInitializer.cs | 14 + .../Persistence/MediumMessage.cs | 18 + .../Processor/ICollectProcessor.cs | 9 - .../Processor/IDispatcher.Default.cs | 22 +- .../Processor/IProcessingServer.Cap.cs | 2 +- .../Processor/IProcessor.Collector.cs | 60 +++ .../Processor/IProcessor.NeedRetry.cs | 18 +- .../Processor/States/IState.Failed.cs | 25 -- .../Processor/States/IState.Scheduled.cs | 25 -- .../Processor/States/IState.Succeeded.cs | 35 -- src/DotNetCore.CAP/Processor/States/IState.cs | 19 - .../Processor/States/IStateChanger.Default.cs | 45 -- .../States/IStateChanger.Extensions.cs | 31 -- .../Processor/States/IStateChanger.cs | 14 - .../Serialization/ISerializer.cs | 18 + .../Serialization/StringSerializer.cs | 27 ++ src/DotNetCore.CAP/Transport/ITransport.cs | 12 + .../MongoDBMonitoringApiTest.cs | 2 +- .../MongoDBStorageConnectionTest.cs | 2 +- .../MySqlStorageConnectionTest.cs | 2 +- .../PostgreSqlStorageConnectionTest.cs | 2 +- .../SqlServerStorageConnectionTest.cs | 2 +- test/DotNetCore.CAP.Test/CAP.BuilderTest.cs | 9 +- .../CallbackMessageSenderTest.cs | 2 +- .../ConsumerInvokerTest.cs | 2 +- .../JsonContentSerializerTest.cs | 2 +- .../Processor/StateChangerTest.cs | 2 +- test/DotNetCore.CAP.Test/Sample.cs | 1 - 226 files changed, 1777 insertions(+), 1956 deletions(-) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/BatchCommandDispatcher.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/CAP.DashboardMiddleware.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/CAP.DashboardOptions.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/CAP.DashboardOptionsExtensions.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/CombinedResourceDispatcher.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/CommandDispatcher.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/css/bootstrap.min.css (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/css/cap.css (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/css/jsonview.min.css (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/css/rickshaw.min.css (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/fonts/glyphicons-halflings-regular.eot (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/fonts/glyphicons-halflings-regular.svg (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/fonts/glyphicons-halflings-regular.ttf (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/fonts/glyphicons-halflings-regular.woff (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/fonts/glyphicons-halflings-regular.woff2 (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/bootstrap.min.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/cap.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/d3.layout.min.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/d3.min.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/jquery-2.1.4.min.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/jsonview.min.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/moment-with-locales.min.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/moment.min.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/js/rickshaw.min.js (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/resx/Strings.Designer.cs (99%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/resx/Strings.resx (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Content/resx/Strings.zh.resx (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/DashboardContext.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/DashboardMetric.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/DashboardMetrics.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/DashboardRequest.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/DashboardResponse.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/DashboardRoutes.cs (100%) create mode 100644 src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/EmbeddedResourceDispatcher.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/DownstreamUrl.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/GatewayProxyMiddleware.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/IRequestMapper.Default.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/IRequestMapper.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/Requester/HttpClientBuilder.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/Requester/HttpClientHttpRequester.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/Requester/IHttpClient.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/Requester/IHttpClientBuilder.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/Requester/IHttpClientCache.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/Requester/IHttpRequester.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/GatewayProxy/Requester/MemoryHttpClientCache.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/HtmlHelper.cs (99%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/IDashboardAuthorizationFilter.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/IDashboardDispatcher.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/IMonitoringApi.cs (95%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/JsonDispatcher.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/JsonStats.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/LocalRequestsOnlyAuthorizationFilter.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/MenuItem.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/MessageHistoryRenderer.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/MessagesSidebarMenu.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Metric.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Monitoring/MessageDto.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Monitoring/MessageQueryDto.cs (94%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Monitoring/ServerDto.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Monitoring/StatisticsDto.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/NavigationMenu.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/NonEscapedString.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pager.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/BlockMetric.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/Breadcrumbs.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/HomePage.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/HomePage.cshtml (98%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/HomePage.generated.cs (99%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/InlineMetric.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/LayoutPage.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/LayoutPage.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/LayoutPage.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/NodePage.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/NodePage.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/NodePage.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/PublishedPage.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/PublishedPage.cshtml (99%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/PublishedPage.generated.cs (99%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/ReceivedPage.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/ReceivedPage.cshtml (99%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/ReceivedPage.generated.cs (99%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/SidebarMenu.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/SubscriberPage.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/SubscriberPage.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_BlockMetric.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_BlockMetric.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_Breadcrumbs.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_Breadcrumbs.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_InlineMetric.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_InlineMetric.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_Navigation.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_Navigation.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_Paginator.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_Paginator.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_Paginator.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_PerPageSelector.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_PerPageSelector.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_PerPageSelector.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_SidebarMenu.cshtml (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/Pages/_SidebarMenu.generated.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/RazorPage.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/RazorPageDispatcher.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/RouteCollection.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/RouteCollectionExtensions.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/TimelineCounter.cs (100%) rename src/{DotNetCore.CAP/Dashboard => DotNetCore.CAP.Dashboard}/UrlHelper.cs (100%) delete mode 100644 src/DotNetCore.CAP.MySql/ICapPublisher.MySql.cs delete mode 100644 src/DotNetCore.CAP.MySql/ICollectProcessor.MySql.cs delete mode 100644 src/DotNetCore.CAP.MySql/IStorageConnection.MySql.cs delete mode 100644 src/DotNetCore.CAP.MySql/IStorageTransaction.MySql.cs create mode 100644 src/DotNetCore.CAP.MySql/MySqlDataStorage.cs create mode 100644 src/DotNetCore.CAP/Abstractions/CapPublisher.cs delete mode 100644 src/DotNetCore.CAP/Abstractions/CapPublisherBase.cs delete mode 100644 src/DotNetCore.CAP/IPublishExecutor.cs delete mode 100644 src/DotNetCore.CAP/IPublishMessageSender.Base.cs delete mode 100644 src/DotNetCore.CAP/IPublishMessageSender.cs delete mode 100644 src/DotNetCore.CAP/IStorage.cs delete mode 100644 src/DotNetCore.CAP/IStorageTransaction.cs delete mode 100644 src/DotNetCore.CAP/Internal/ICallbackMessageSender.Default.cs create mode 100644 src/DotNetCore.CAP/Internal/IMessageSender.Default.cs rename src/DotNetCore.CAP/Internal/{ICallbackMessageSender.cs => IMessageSender.cs} (64%) delete mode 100644 src/DotNetCore.CAP/MessageContext.cs rename src/DotNetCore.CAP/{Models => Messages}/CapMessageDto.cs (91%) create mode 100644 src/DotNetCore.CAP/Messages/Headers.cs create mode 100644 src/DotNetCore.CAP/Messages/Message.cs rename src/DotNetCore.CAP/{Models => Messages}/MessageType.cs (87%) create mode 100644 src/DotNetCore.CAP/Messages/TransportMessage.cs delete mode 100644 src/DotNetCore.CAP/Models/CapReceivedMessage.cs create mode 100644 src/DotNetCore.CAP/Persistence/CapPublishedMessage.cs rename src/DotNetCore.CAP/{Models/CapPublishedMessage.cs => Persistence/CapReceivedMessage.cs} (68%) create mode 100644 src/DotNetCore.CAP/Persistence/IDashboardQuerying.cs create mode 100644 src/DotNetCore.CAP/Persistence/IDataStorage.cs create mode 100644 src/DotNetCore.CAP/Persistence/IStorageInitializer.cs create mode 100644 src/DotNetCore.CAP/Persistence/MediumMessage.cs delete mode 100644 src/DotNetCore.CAP/Processor/ICollectProcessor.cs create mode 100644 src/DotNetCore.CAP/Processor/IProcessor.Collector.cs delete mode 100644 src/DotNetCore.CAP/Processor/States/IState.Failed.cs delete mode 100644 src/DotNetCore.CAP/Processor/States/IState.Scheduled.cs delete mode 100644 src/DotNetCore.CAP/Processor/States/IState.Succeeded.cs delete mode 100644 src/DotNetCore.CAP/Processor/States/IState.cs delete mode 100644 src/DotNetCore.CAP/Processor/States/IStateChanger.Default.cs delete mode 100644 src/DotNetCore.CAP/Processor/States/IStateChanger.Extensions.cs delete mode 100644 src/DotNetCore.CAP/Processor/States/IStateChanger.cs create mode 100644 src/DotNetCore.CAP/Serialization/ISerializer.cs create mode 100644 src/DotNetCore.CAP/Serialization/StringSerializer.cs create mode 100644 src/DotNetCore.CAP/Transport/ITransport.cs diff --git a/CAP.sln b/CAP.sln index 21c804b..f9bcb17 100644 --- a/CAP.sln +++ b/CAP.sln @@ -68,6 +68,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.InMemoryStor EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AzureServiceBus.InMemory", "samples\Sample.AzureServiceBus.InMemory\Sample.AzureServiceBus.InMemory.csproj", "{1E1E959C-3D0E-45C3-ABCA-DAAACE68AAB8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetCore.CAP.Dashboard", "src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj", "{56FB261C-67AF-4715-9A46-4FA4FAB91B2C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -142,6 +144,10 @@ Global {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -165,6 +171,7 @@ Global {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2E70565D-94CF-40B4-BFE1-AC18D5F736AB} diff --git a/samples/Sample.RabbitMQ.MySql/Controllers/ValuesController.cs b/samples/Sample.RabbitMQ.MySql/Controllers/ValuesController.cs index a9c2c96..578e201 100644 --- a/samples/Sample.RabbitMQ.MySql/Controllers/ValuesController.cs +++ b/samples/Sample.RabbitMQ.MySql/Controllers/ValuesController.cs @@ -36,10 +36,10 @@ namespace Sample.RabbitMQ.MySql.Controllers //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); - } + //for (int i = 0; i < 5; i++) + //{ + _capBus.Publish("sample.rabbitmq.mysql", DateTime.Now); + //} transaction.Commit(); } @@ -68,10 +68,10 @@ namespace Sample.RabbitMQ.MySql.Controllers } [NonAction] - [CapSubscribe("#.rabbitmq.mysql")] + [CapSubscribe("sample.rabbitmq.mysql")] public void Subscriber(DateTime time) { - Console.WriteLine($@"{DateTime.Now}, Subscriber invoked, Sent time:{time}"); + //Console.WriteLine($@"{DateTime.Now}, Subscriber invoked, Sent time:{time}"); } } } diff --git a/samples/Sample.RabbitMQ.MySql/Program.cs b/samples/Sample.RabbitMQ.MySql/Program.cs index d8e6083..80d0fe6 100644 --- a/samples/Sample.RabbitMQ.MySql/Program.cs +++ b/samples/Sample.RabbitMQ.MySql/Program.cs @@ -13,6 +13,7 @@ namespace Sample.RabbitMQ.MySql public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup() + .UseUrls("http://*:15173") .Build(); } } diff --git a/samples/Sample.RabbitMQ.MySql/Properties/launchSettings.json b/samples/Sample.RabbitMQ.MySql/Properties/launchSettings.json index 369b41c..c0a90d4 100644 --- a/samples/Sample.RabbitMQ.MySql/Properties/launchSettings.json +++ b/samples/Sample.RabbitMQ.MySql/Properties/launchSettings.json @@ -21,7 +21,7 @@ "launchBrowser": true, "launchUrl": "cap", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Production" }, "applicationUrl": "http://localhost:57173/" } diff --git a/samples/Sample.RabbitMQ.MySql/Startup.cs b/samples/Sample.RabbitMQ.MySql/Startup.cs index b9f16e7..cf6b8f8 100644 --- a/samples/Sample.RabbitMQ.MySql/Startup.cs +++ b/samples/Sample.RabbitMQ.MySql/Startup.cs @@ -15,12 +15,13 @@ namespace Sample.RabbitMQ.MySql services.AddCap(x => { x.UseEntityFramework(); - x.UseRabbitMQ("localhost"); + x.UseRabbitMQ("192.168.2.120"); x.UseDashboard(); x.FailedRetryCount = 5; x.FailedThresholdCallback = (type, name, content) => { - 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: {name}, message body: {content}"); }; }); diff --git a/samples/Sample.RabbitMQ.MySql/appsettings.json b/samples/Sample.RabbitMQ.MySql/appsettings.json index 20aa907..50fe9a3 100644 --- a/samples/Sample.RabbitMQ.MySql/appsettings.json +++ b/samples/Sample.RabbitMQ.MySql/appsettings.json @@ -2,7 +2,7 @@ "Logging": { "IncludeScopes": false, "LogLevel": { - "Default": "Debug" + "Default": "Error" } } } diff --git a/src/DotNetCore.CAP.AzureServiceBus/CAP.AzureServiceBusOptionsExtension.cs b/src/DotNetCore.CAP.AzureServiceBus/CAP.AzureServiceBusOptionsExtension.cs index 395c0f0..1a2feac 100644 --- a/src/DotNetCore.CAP.AzureServiceBus/CAP.AzureServiceBusOptionsExtension.cs +++ b/src/DotNetCore.CAP.AzureServiceBus/CAP.AzureServiceBusOptionsExtension.cs @@ -24,7 +24,7 @@ namespace DotNetCore.CAP services.Configure(_configure); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); } } diff --git a/src/DotNetCore.CAP/Dashboard/BatchCommandDispatcher.cs b/src/DotNetCore.CAP.Dashboard/BatchCommandDispatcher.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/BatchCommandDispatcher.cs rename to src/DotNetCore.CAP.Dashboard/BatchCommandDispatcher.cs diff --git a/src/DotNetCore.CAP/Dashboard/CAP.DashboardMiddleware.cs b/src/DotNetCore.CAP.Dashboard/CAP.DashboardMiddleware.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/CAP.DashboardMiddleware.cs rename to src/DotNetCore.CAP.Dashboard/CAP.DashboardMiddleware.cs diff --git a/src/DotNetCore.CAP/Dashboard/CAP.DashboardOptions.cs b/src/DotNetCore.CAP.Dashboard/CAP.DashboardOptions.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/CAP.DashboardOptions.cs rename to src/DotNetCore.CAP.Dashboard/CAP.DashboardOptions.cs diff --git a/src/DotNetCore.CAP/Dashboard/CAP.DashboardOptionsExtensions.cs b/src/DotNetCore.CAP.Dashboard/CAP.DashboardOptionsExtensions.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/CAP.DashboardOptionsExtensions.cs rename to src/DotNetCore.CAP.Dashboard/CAP.DashboardOptionsExtensions.cs diff --git a/src/DotNetCore.CAP/Dashboard/CombinedResourceDispatcher.cs b/src/DotNetCore.CAP.Dashboard/CombinedResourceDispatcher.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/CombinedResourceDispatcher.cs rename to src/DotNetCore.CAP.Dashboard/CombinedResourceDispatcher.cs diff --git a/src/DotNetCore.CAP/Dashboard/CommandDispatcher.cs b/src/DotNetCore.CAP.Dashboard/CommandDispatcher.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/CommandDispatcher.cs rename to src/DotNetCore.CAP.Dashboard/CommandDispatcher.cs diff --git a/src/DotNetCore.CAP/Dashboard/Content/css/bootstrap.min.css b/src/DotNetCore.CAP.Dashboard/Content/css/bootstrap.min.css similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/css/bootstrap.min.css rename to src/DotNetCore.CAP.Dashboard/Content/css/bootstrap.min.css diff --git a/src/DotNetCore.CAP/Dashboard/Content/css/cap.css b/src/DotNetCore.CAP.Dashboard/Content/css/cap.css similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/css/cap.css rename to src/DotNetCore.CAP.Dashboard/Content/css/cap.css diff --git a/src/DotNetCore.CAP/Dashboard/Content/css/jsonview.min.css b/src/DotNetCore.CAP.Dashboard/Content/css/jsonview.min.css similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/css/jsonview.min.css rename to src/DotNetCore.CAP.Dashboard/Content/css/jsonview.min.css diff --git a/src/DotNetCore.CAP/Dashboard/Content/css/rickshaw.min.css b/src/DotNetCore.CAP.Dashboard/Content/css/rickshaw.min.css similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/css/rickshaw.min.css rename to src/DotNetCore.CAP.Dashboard/Content/css/rickshaw.min.css diff --git a/src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.eot b/src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.eot rename to src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.eot diff --git a/src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.svg b/src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.svg rename to src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.svg diff --git a/src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.ttf b/src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.ttf rename to src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.ttf diff --git a/src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.woff b/src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.woff rename to src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.woff diff --git a/src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.woff2 b/src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/fonts/glyphicons-halflings-regular.woff2 rename to src/DotNetCore.CAP.Dashboard/Content/fonts/glyphicons-halflings-regular.woff2 diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/bootstrap.min.js b/src/DotNetCore.CAP.Dashboard/Content/js/bootstrap.min.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/bootstrap.min.js rename to src/DotNetCore.CAP.Dashboard/Content/js/bootstrap.min.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/cap.js b/src/DotNetCore.CAP.Dashboard/Content/js/cap.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/cap.js rename to src/DotNetCore.CAP.Dashboard/Content/js/cap.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/d3.layout.min.js b/src/DotNetCore.CAP.Dashboard/Content/js/d3.layout.min.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/d3.layout.min.js rename to src/DotNetCore.CAP.Dashboard/Content/js/d3.layout.min.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/d3.min.js b/src/DotNetCore.CAP.Dashboard/Content/js/d3.min.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/d3.min.js rename to src/DotNetCore.CAP.Dashboard/Content/js/d3.min.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/jquery-2.1.4.min.js b/src/DotNetCore.CAP.Dashboard/Content/js/jquery-2.1.4.min.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/jquery-2.1.4.min.js rename to src/DotNetCore.CAP.Dashboard/Content/js/jquery-2.1.4.min.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/jsonview.min.js b/src/DotNetCore.CAP.Dashboard/Content/js/jsonview.min.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/jsonview.min.js rename to src/DotNetCore.CAP.Dashboard/Content/js/jsonview.min.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/moment-with-locales.min.js b/src/DotNetCore.CAP.Dashboard/Content/js/moment-with-locales.min.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/moment-with-locales.min.js rename to src/DotNetCore.CAP.Dashboard/Content/js/moment-with-locales.min.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/moment.min.js b/src/DotNetCore.CAP.Dashboard/Content/js/moment.min.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/moment.min.js rename to src/DotNetCore.CAP.Dashboard/Content/js/moment.min.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/js/rickshaw.min.js b/src/DotNetCore.CAP.Dashboard/Content/js/rickshaw.min.js similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/js/rickshaw.min.js rename to src/DotNetCore.CAP.Dashboard/Content/js/rickshaw.min.js diff --git a/src/DotNetCore.CAP/Dashboard/Content/resx/Strings.Designer.cs b/src/DotNetCore.CAP.Dashboard/Content/resx/Strings.Designer.cs similarity index 99% rename from src/DotNetCore.CAP/Dashboard/Content/resx/Strings.Designer.cs rename to src/DotNetCore.CAP.Dashboard/Content/resx/Strings.Designer.cs index 4f911c2..38eb369 100644 --- a/src/DotNetCore.CAP/Dashboard/Content/resx/Strings.Designer.cs +++ b/src/DotNetCore.CAP.Dashboard/Content/resx/Strings.Designer.cs @@ -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 { diff --git a/src/DotNetCore.CAP/Dashboard/Content/resx/Strings.resx b/src/DotNetCore.CAP.Dashboard/Content/resx/Strings.resx similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/resx/Strings.resx rename to src/DotNetCore.CAP.Dashboard/Content/resx/Strings.resx diff --git a/src/DotNetCore.CAP/Dashboard/Content/resx/Strings.zh.resx b/src/DotNetCore.CAP.Dashboard/Content/resx/Strings.zh.resx similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Content/resx/Strings.zh.resx rename to src/DotNetCore.CAP.Dashboard/Content/resx/Strings.zh.resx diff --git a/src/DotNetCore.CAP/Dashboard/DashboardContext.cs b/src/DotNetCore.CAP.Dashboard/DashboardContext.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/DashboardContext.cs rename to src/DotNetCore.CAP.Dashboard/DashboardContext.cs diff --git a/src/DotNetCore.CAP/Dashboard/DashboardMetric.cs b/src/DotNetCore.CAP.Dashboard/DashboardMetric.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/DashboardMetric.cs rename to src/DotNetCore.CAP.Dashboard/DashboardMetric.cs diff --git a/src/DotNetCore.CAP/Dashboard/DashboardMetrics.cs b/src/DotNetCore.CAP.Dashboard/DashboardMetrics.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/DashboardMetrics.cs rename to src/DotNetCore.CAP.Dashboard/DashboardMetrics.cs diff --git a/src/DotNetCore.CAP/Dashboard/DashboardRequest.cs b/src/DotNetCore.CAP.Dashboard/DashboardRequest.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/DashboardRequest.cs rename to src/DotNetCore.CAP.Dashboard/DashboardRequest.cs diff --git a/src/DotNetCore.CAP/Dashboard/DashboardResponse.cs b/src/DotNetCore.CAP.Dashboard/DashboardResponse.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/DashboardResponse.cs rename to src/DotNetCore.CAP.Dashboard/DashboardResponse.cs diff --git a/src/DotNetCore.CAP/Dashboard/DashboardRoutes.cs b/src/DotNetCore.CAP.Dashboard/DashboardRoutes.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/DashboardRoutes.cs rename to src/DotNetCore.CAP.Dashboard/DashboardRoutes.cs diff --git a/src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj b/src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj new file mode 100644 index 0000000..1d40d14 --- /dev/null +++ b/src/DotNetCore.CAP.Dashboard/DotNetCore.CAP.Dashboard.csproj @@ -0,0 +1,125 @@ + + + + netstandard2.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Strings.resx + + + _SidebarMenu.cshtml + + + _SidebarMenu.cshtml + + + ReceivedPage.cshtml + + + ReceivedPage.cshtml + + + _BlockMetric.cshtml + + + _BlockMetric.cshtml + + + _Breadcrumbs.cshtml + + + _Breadcrumbs.cshtml + + + _Paginator.cshtml + + + _Paginator.cshtml + + + _PerPageSelector.cshtml + + + _PerPageSelector.cshtml + + + PublishedPage.cshtml + + + PublishedPage.cshtml + + + LayoutPage.cshtml + + + LayoutPage.cshtml + + + _InlineMetric.cshtml + + + _InlineMetric.cshtml + + + _Navigation.cshtml + + + HomePage.cshtml + + + HomePage.cshtml + + + SubscriberPage.cshtml + + + NodePage.cshtml + + + + + + DotNetCore.CAP.Dashboard.Resources + Strings.Designer.cs + PublicResXFileCodeGenerator + + + + + + PublicResXFileCodeGenerator + DotNetCore.CAP.Dashboard.Resources + Strings.Designer.cs + + + + diff --git a/src/DotNetCore.CAP/Dashboard/EmbeddedResourceDispatcher.cs b/src/DotNetCore.CAP.Dashboard/EmbeddedResourceDispatcher.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/EmbeddedResourceDispatcher.cs rename to src/DotNetCore.CAP.Dashboard/EmbeddedResourceDispatcher.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/DownstreamUrl.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/DownstreamUrl.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/DownstreamUrl.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/DownstreamUrl.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/GatewayProxyMiddleware.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/GatewayProxyMiddleware.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/GatewayProxyMiddleware.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/GatewayProxyMiddleware.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/IRequestMapper.Default.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/IRequestMapper.Default.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/IRequestMapper.Default.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/IRequestMapper.Default.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/IRequestMapper.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/IRequestMapper.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/IRequestMapper.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/IRequestMapper.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/HttpClientBuilder.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/HttpClientBuilder.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/HttpClientBuilder.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/HttpClientBuilder.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/HttpClientHttpRequester.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/HttpClientHttpRequester.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/HttpClientHttpRequester.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/HttpClientHttpRequester.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClient.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClient.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClient.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClient.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClientBuilder.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClientBuilder.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClientBuilder.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClientBuilder.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClientCache.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClientCache.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpClientCache.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpClientCache.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpRequester.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpRequester.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/IHttpRequester.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/IHttpRequester.cs diff --git a/src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/MemoryHttpClientCache.cs b/src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/MemoryHttpClientCache.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/GatewayProxy/Requester/MemoryHttpClientCache.cs rename to src/DotNetCore.CAP.Dashboard/GatewayProxy/Requester/MemoryHttpClientCache.cs diff --git a/src/DotNetCore.CAP/Dashboard/HtmlHelper.cs b/src/DotNetCore.CAP.Dashboard/HtmlHelper.cs similarity index 99% rename from src/DotNetCore.CAP/Dashboard/HtmlHelper.cs rename to src/DotNetCore.CAP.Dashboard/HtmlHelper.cs index dad4664..6b896a7 100644 --- a/src/DotNetCore.CAP/Dashboard/HtmlHelper.cs +++ b/src/DotNetCore.CAP.Dashboard/HtmlHelper.cs @@ -11,7 +11,7 @@ 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.Messages; using Microsoft.Extensions.Internal; namespace DotNetCore.CAP.Dashboard diff --git a/src/DotNetCore.CAP/Dashboard/IDashboardAuthorizationFilter.cs b/src/DotNetCore.CAP.Dashboard/IDashboardAuthorizationFilter.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/IDashboardAuthorizationFilter.cs rename to src/DotNetCore.CAP.Dashboard/IDashboardAuthorizationFilter.cs diff --git a/src/DotNetCore.CAP/Dashboard/IDashboardDispatcher.cs b/src/DotNetCore.CAP.Dashboard/IDashboardDispatcher.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/IDashboardDispatcher.cs rename to src/DotNetCore.CAP.Dashboard/IDashboardDispatcher.cs diff --git a/src/DotNetCore.CAP/Dashboard/IMonitoringApi.cs b/src/DotNetCore.CAP.Dashboard/IMonitoringApi.cs similarity index 95% rename from src/DotNetCore.CAP/Dashboard/IMonitoringApi.cs rename to src/DotNetCore.CAP.Dashboard/IMonitoringApi.cs index e5ecd71..bc8505e 100644 --- a/src/DotNetCore.CAP/Dashboard/IMonitoringApi.cs +++ b/src/DotNetCore.CAP.Dashboard/IMonitoringApi.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using DotNetCore.CAP.Dashboard.Monitoring; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Dashboard { diff --git a/src/DotNetCore.CAP/Dashboard/JsonDispatcher.cs b/src/DotNetCore.CAP.Dashboard/JsonDispatcher.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/JsonDispatcher.cs rename to src/DotNetCore.CAP.Dashboard/JsonDispatcher.cs diff --git a/src/DotNetCore.CAP/Dashboard/JsonStats.cs b/src/DotNetCore.CAP.Dashboard/JsonStats.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/JsonStats.cs rename to src/DotNetCore.CAP.Dashboard/JsonStats.cs diff --git a/src/DotNetCore.CAP/Dashboard/LocalRequestsOnlyAuthorizationFilter.cs b/src/DotNetCore.CAP.Dashboard/LocalRequestsOnlyAuthorizationFilter.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/LocalRequestsOnlyAuthorizationFilter.cs rename to src/DotNetCore.CAP.Dashboard/LocalRequestsOnlyAuthorizationFilter.cs diff --git a/src/DotNetCore.CAP/Dashboard/MenuItem.cs b/src/DotNetCore.CAP.Dashboard/MenuItem.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/MenuItem.cs rename to src/DotNetCore.CAP.Dashboard/MenuItem.cs diff --git a/src/DotNetCore.CAP/Dashboard/MessageHistoryRenderer.cs b/src/DotNetCore.CAP.Dashboard/MessageHistoryRenderer.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/MessageHistoryRenderer.cs rename to src/DotNetCore.CAP.Dashboard/MessageHistoryRenderer.cs diff --git a/src/DotNetCore.CAP/Dashboard/MessagesSidebarMenu.cs b/src/DotNetCore.CAP.Dashboard/MessagesSidebarMenu.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/MessagesSidebarMenu.cs rename to src/DotNetCore.CAP.Dashboard/MessagesSidebarMenu.cs diff --git a/src/DotNetCore.CAP/Dashboard/Metric.cs b/src/DotNetCore.CAP.Dashboard/Metric.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Metric.cs rename to src/DotNetCore.CAP.Dashboard/Metric.cs diff --git a/src/DotNetCore.CAP/Dashboard/Monitoring/MessageDto.cs b/src/DotNetCore.CAP.Dashboard/Monitoring/MessageDto.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Monitoring/MessageDto.cs rename to src/DotNetCore.CAP.Dashboard/Monitoring/MessageDto.cs diff --git a/src/DotNetCore.CAP/Dashboard/Monitoring/MessageQueryDto.cs b/src/DotNetCore.CAP.Dashboard/Monitoring/MessageQueryDto.cs similarity index 94% rename from src/DotNetCore.CAP/Dashboard/Monitoring/MessageQueryDto.cs rename to src/DotNetCore.CAP.Dashboard/Monitoring/MessageQueryDto.cs index 02da29b..61c4706 100644 --- a/src/DotNetCore.CAP/Dashboard/Monitoring/MessageQueryDto.cs +++ b/src/DotNetCore.CAP.Dashboard/Monitoring/MessageQueryDto.cs @@ -1,7 +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.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Dashboard.Monitoring { diff --git a/src/DotNetCore.CAP/Dashboard/Monitoring/ServerDto.cs b/src/DotNetCore.CAP.Dashboard/Monitoring/ServerDto.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Monitoring/ServerDto.cs rename to src/DotNetCore.CAP.Dashboard/Monitoring/ServerDto.cs diff --git a/src/DotNetCore.CAP/Dashboard/Monitoring/StatisticsDto.cs b/src/DotNetCore.CAP.Dashboard/Monitoring/StatisticsDto.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Monitoring/StatisticsDto.cs rename to src/DotNetCore.CAP.Dashboard/Monitoring/StatisticsDto.cs diff --git a/src/DotNetCore.CAP/Dashboard/NavigationMenu.cs b/src/DotNetCore.CAP.Dashboard/NavigationMenu.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/NavigationMenu.cs rename to src/DotNetCore.CAP.Dashboard/NavigationMenu.cs diff --git a/src/DotNetCore.CAP/Dashboard/NonEscapedString.cs b/src/DotNetCore.CAP.Dashboard/NonEscapedString.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/NonEscapedString.cs rename to src/DotNetCore.CAP.Dashboard/NonEscapedString.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pager.cs b/src/DotNetCore.CAP.Dashboard/Pager.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pager.cs rename to src/DotNetCore.CAP.Dashboard/Pager.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/BlockMetric.cs b/src/DotNetCore.CAP.Dashboard/Pages/BlockMetric.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/BlockMetric.cs rename to src/DotNetCore.CAP.Dashboard/Pages/BlockMetric.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/Breadcrumbs.cs b/src/DotNetCore.CAP.Dashboard/Pages/Breadcrumbs.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/Breadcrumbs.cs rename to src/DotNetCore.CAP.Dashboard/Pages/Breadcrumbs.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/HomePage.cs b/src/DotNetCore.CAP.Dashboard/Pages/HomePage.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/HomePage.cs rename to src/DotNetCore.CAP.Dashboard/Pages/HomePage.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/HomePage.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/HomePage.cshtml similarity index 98% rename from src/DotNetCore.CAP/Dashboard/Pages/HomePage.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/HomePage.cshtml index a416980..91b840d 100644 --- a/src/DotNetCore.CAP/Dashboard/Pages/HomePage.cshtml +++ b/src/DotNetCore.CAP.Dashboard/Pages/HomePage.cshtml @@ -1,7 +1,7 @@ @* Generator: Template TypeVisibility: Internal GeneratePrettyNames: True *@ @using DotNetCore.CAP.Dashboard.Pages @using DotNetCore.CAP.Dashboard.Resources -@using DotNetCore.CAP.Models +@using DotNetCore.CAP.Messages @using Newtonsoft.Json @inherits DotNetCore.CAP.Dashboard.RazorPage @{ diff --git a/src/DotNetCore.CAP/Dashboard/Pages/HomePage.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/HomePage.generated.cs similarity index 99% rename from src/DotNetCore.CAP/Dashboard/Pages/HomePage.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/HomePage.generated.cs index d9b3137..12947d4 100644 --- a/src/DotNetCore.CAP/Dashboard/Pages/HomePage.generated.cs +++ b/src/DotNetCore.CAP.Dashboard/Pages/HomePage.generated.cs @@ -1,4 +1,6 @@ -#pragma warning disable 1591 +using DotNetCore.CAP.Messages; + +#pragma warning disable 1591 //------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -45,8 +47,6 @@ namespace DotNetCore.CAP.Dashboard.Pages #line hidden #line 4 "..\..\HomePage.cshtml" - using DotNetCore.CAP.Models; - #line default #line hidden diff --git a/src/DotNetCore.CAP/Dashboard/Pages/InlineMetric.cs b/src/DotNetCore.CAP.Dashboard/Pages/InlineMetric.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/InlineMetric.cs rename to src/DotNetCore.CAP.Dashboard/Pages/InlineMetric.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/LayoutPage.cs b/src/DotNetCore.CAP.Dashboard/Pages/LayoutPage.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/LayoutPage.cs rename to src/DotNetCore.CAP.Dashboard/Pages/LayoutPage.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/LayoutPage.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/LayoutPage.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/LayoutPage.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/LayoutPage.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/LayoutPage.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/LayoutPage.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/LayoutPage.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/LayoutPage.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/NodePage.cs b/src/DotNetCore.CAP.Dashboard/Pages/NodePage.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/NodePage.cs rename to src/DotNetCore.CAP.Dashboard/Pages/NodePage.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/NodePage.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/NodePage.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/NodePage.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/NodePage.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/NodePage.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/NodePage.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/NodePage.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/NodePage.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/PublishedPage.cs b/src/DotNetCore.CAP.Dashboard/Pages/PublishedPage.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/PublishedPage.cs rename to src/DotNetCore.CAP.Dashboard/Pages/PublishedPage.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/PublishedPage.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/PublishedPage.cshtml similarity index 99% rename from src/DotNetCore.CAP/Dashboard/Pages/PublishedPage.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/PublishedPage.cshtml index 2d76089..d4313db 100644 --- a/src/DotNetCore.CAP/Dashboard/Pages/PublishedPage.cshtml +++ b/src/DotNetCore.CAP.Dashboard/Pages/PublishedPage.cshtml @@ -4,7 +4,7 @@ @using DotNetCore.CAP.Dashboard.Monitoring @using DotNetCore.CAP.Dashboard.Pages @using DotNetCore.CAP.Dashboard.Resources -@using DotNetCore.CAP.Models +@using DotNetCore.CAP.Messages @inherits DotNetCore.CAP.Dashboard.RazorPage @{ Layout = new LayoutPage(Strings.PublishedMessagesPage_Title); diff --git a/src/DotNetCore.CAP/Dashboard/Pages/PublishedPage.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/PublishedPage.generated.cs similarity index 99% rename from src/DotNetCore.CAP/Dashboard/Pages/PublishedPage.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/PublishedPage.generated.cs index 4d8a578..250c6c8 100644 --- a/src/DotNetCore.CAP/Dashboard/Pages/PublishedPage.generated.cs +++ b/src/DotNetCore.CAP.Dashboard/Pages/PublishedPage.generated.cs @@ -1,4 +1,6 @@ -#pragma warning disable 1591 +using DotNetCore.CAP.Messages; + +#pragma warning disable 1591 //------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -46,7 +48,6 @@ namespace DotNetCore.CAP.Dashboard.Pages #line hidden #line 3 "..\..\PublishedPage.cshtml" - using DotNetCore.CAP.Models; #line default #line hidden diff --git a/src/DotNetCore.CAP/Dashboard/Pages/ReceivedPage.cs b/src/DotNetCore.CAP.Dashboard/Pages/ReceivedPage.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/ReceivedPage.cs rename to src/DotNetCore.CAP.Dashboard/Pages/ReceivedPage.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/ReceivedPage.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/ReceivedPage.cshtml similarity index 99% rename from src/DotNetCore.CAP/Dashboard/Pages/ReceivedPage.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/ReceivedPage.cshtml index 5b92167..fb179cf 100644 --- a/src/DotNetCore.CAP/Dashboard/Pages/ReceivedPage.cshtml +++ b/src/DotNetCore.CAP.Dashboard/Pages/ReceivedPage.cshtml @@ -4,7 +4,7 @@ @using DotNetCore.CAP.Dashboard.Monitoring @using DotNetCore.CAP.Dashboard.Pages @using DotNetCore.CAP.Dashboard.Resources -@using DotNetCore.CAP.Models +@using DotNetCore.CAP.Messages @inherits DotNetCore.CAP.Dashboard.RazorPage @{ Layout = new LayoutPage(Strings.ReceivedMessagesPage_Title); diff --git a/src/DotNetCore.CAP/Dashboard/Pages/ReceivedPage.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/ReceivedPage.generated.cs similarity index 99% rename from src/DotNetCore.CAP/Dashboard/Pages/ReceivedPage.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/ReceivedPage.generated.cs index 7b78863..17365c7 100644 --- a/src/DotNetCore.CAP/Dashboard/Pages/ReceivedPage.generated.cs +++ b/src/DotNetCore.CAP.Dashboard/Pages/ReceivedPage.generated.cs @@ -1,4 +1,6 @@ -#pragma warning disable 1591 +using DotNetCore.CAP.Messages; + +#pragma warning disable 1591 //------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -46,7 +48,6 @@ namespace DotNetCore.CAP.Dashboard.Pages #line hidden #line 3 "..\..\ReceivedPage.cshtml" - using DotNetCore.CAP.Models; #line default #line hidden diff --git a/src/DotNetCore.CAP/Dashboard/Pages/SidebarMenu.cs b/src/DotNetCore.CAP.Dashboard/Pages/SidebarMenu.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/SidebarMenu.cs rename to src/DotNetCore.CAP.Dashboard/Pages/SidebarMenu.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/SubscriberPage.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/SubscriberPage.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/SubscriberPage.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/SubscriberPage.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/SubscriberPage.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/SubscriberPage.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/SubscriberPage.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/SubscriberPage.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_BlockMetric.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/_BlockMetric.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_BlockMetric.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/_BlockMetric.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_BlockMetric.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/_BlockMetric.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_BlockMetric.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_BlockMetric.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_Breadcrumbs.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/_Breadcrumbs.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_Breadcrumbs.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/_Breadcrumbs.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_Breadcrumbs.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/_Breadcrumbs.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_Breadcrumbs.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_Breadcrumbs.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_InlineMetric.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/_InlineMetric.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_InlineMetric.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/_InlineMetric.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_InlineMetric.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/_InlineMetric.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_InlineMetric.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_InlineMetric.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_Navigation.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/_Navigation.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_Navigation.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/_Navigation.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_Navigation.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/_Navigation.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_Navigation.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_Navigation.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_Paginator.cs b/src/DotNetCore.CAP.Dashboard/Pages/_Paginator.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_Paginator.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_Paginator.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_Paginator.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/_Paginator.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_Paginator.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/_Paginator.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_Paginator.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/_Paginator.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_Paginator.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_Paginator.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_PerPageSelector.cs b/src/DotNetCore.CAP.Dashboard/Pages/_PerPageSelector.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_PerPageSelector.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_PerPageSelector.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_PerPageSelector.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/_PerPageSelector.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_PerPageSelector.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/_PerPageSelector.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_PerPageSelector.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/_PerPageSelector.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_PerPageSelector.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_PerPageSelector.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_SidebarMenu.cshtml b/src/DotNetCore.CAP.Dashboard/Pages/_SidebarMenu.cshtml similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_SidebarMenu.cshtml rename to src/DotNetCore.CAP.Dashboard/Pages/_SidebarMenu.cshtml diff --git a/src/DotNetCore.CAP/Dashboard/Pages/_SidebarMenu.generated.cs b/src/DotNetCore.CAP.Dashboard/Pages/_SidebarMenu.generated.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/Pages/_SidebarMenu.generated.cs rename to src/DotNetCore.CAP.Dashboard/Pages/_SidebarMenu.generated.cs diff --git a/src/DotNetCore.CAP/Dashboard/RazorPage.cs b/src/DotNetCore.CAP.Dashboard/RazorPage.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/RazorPage.cs rename to src/DotNetCore.CAP.Dashboard/RazorPage.cs diff --git a/src/DotNetCore.CAP/Dashboard/RazorPageDispatcher.cs b/src/DotNetCore.CAP.Dashboard/RazorPageDispatcher.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/RazorPageDispatcher.cs rename to src/DotNetCore.CAP.Dashboard/RazorPageDispatcher.cs diff --git a/src/DotNetCore.CAP/Dashboard/RouteCollection.cs b/src/DotNetCore.CAP.Dashboard/RouteCollection.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/RouteCollection.cs rename to src/DotNetCore.CAP.Dashboard/RouteCollection.cs diff --git a/src/DotNetCore.CAP/Dashboard/RouteCollectionExtensions.cs b/src/DotNetCore.CAP.Dashboard/RouteCollectionExtensions.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/RouteCollectionExtensions.cs rename to src/DotNetCore.CAP.Dashboard/RouteCollectionExtensions.cs diff --git a/src/DotNetCore.CAP/Dashboard/TimelineCounter.cs b/src/DotNetCore.CAP.Dashboard/TimelineCounter.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/TimelineCounter.cs rename to src/DotNetCore.CAP.Dashboard/TimelineCounter.cs diff --git a/src/DotNetCore.CAP/Dashboard/UrlHelper.cs b/src/DotNetCore.CAP.Dashboard/UrlHelper.cs similarity index 100% rename from src/DotNetCore.CAP/Dashboard/UrlHelper.cs rename to src/DotNetCore.CAP.Dashboard/UrlHelper.cs diff --git a/src/DotNetCore.CAP.InMemoryStorage/ICapPublisher.InMemory.cs b/src/DotNetCore.CAP.InMemoryStorage/ICapPublisher.InMemory.cs index 12e9f8c..6cb759c 100644 --- a/src/DotNetCore.CAP.InMemoryStorage/ICapPublisher.InMemory.cs +++ b/src/DotNetCore.CAP.InMemoryStorage/ICapPublisher.InMemory.cs @@ -5,7 +5,7 @@ using System; using System.Threading; using System.Threading.Tasks; using DotNetCore.CAP.Abstractions; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.DependencyInjection; namespace DotNetCore.CAP.InMemoryStorage diff --git a/src/DotNetCore.CAP.InMemoryStorage/IMonitoringApi.InMemory.cs b/src/DotNetCore.CAP.InMemoryStorage/IMonitoringApi.InMemory.cs index d96b976..7454435 100644 --- a/src/DotNetCore.CAP.InMemoryStorage/IMonitoringApi.InMemory.cs +++ b/src/DotNetCore.CAP.InMemoryStorage/IMonitoringApi.InMemory.cs @@ -7,7 +7,7 @@ using System.Linq; using DotNetCore.CAP.Dashboard; using DotNetCore.CAP.Dashboard.Monitoring; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.InMemoryStorage { diff --git a/src/DotNetCore.CAP.InMemoryStorage/IStorageConnection.InMemory.cs b/src/DotNetCore.CAP.InMemoryStorage/IStorageConnection.InMemory.cs index 3783ddb..22364b0 100644 --- a/src/DotNetCore.CAP.InMemoryStorage/IStorageConnection.InMemory.cs +++ b/src/DotNetCore.CAP.InMemoryStorage/IStorageConnection.InMemory.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; namespace DotNetCore.CAP.InMemoryStorage diff --git a/src/DotNetCore.CAP.InMemoryStorage/IStorageTransaction.InMemory.cs b/src/DotNetCore.CAP.InMemoryStorage/IStorageTransaction.InMemory.cs index 40bf28f..a63d8a5 100644 --- a/src/DotNetCore.CAP.InMemoryStorage/IStorageTransaction.InMemory.cs +++ b/src/DotNetCore.CAP.InMemoryStorage/IStorageTransaction.InMemory.cs @@ -4,7 +4,7 @@ using System; using System.Linq; using System.Threading.Tasks; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.InMemoryStorage { diff --git a/src/DotNetCore.CAP.Kafka/CAP.KafkaCapOptionsExtension.cs b/src/DotNetCore.CAP.Kafka/CAP.KafkaCapOptionsExtension.cs index 55902e7..6699eb0 100644 --- a/src/DotNetCore.CAP.Kafka/CAP.KafkaCapOptionsExtension.cs +++ b/src/DotNetCore.CAP.Kafka/CAP.KafkaCapOptionsExtension.cs @@ -24,7 +24,7 @@ namespace DotNetCore.CAP services.Configure(_configure); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); } diff --git a/src/DotNetCore.CAP.MongoDB/ICapPublisher.MongoDB.cs b/src/DotNetCore.CAP.MongoDB/ICapPublisher.MongoDB.cs index f74696c..62e2a3e 100644 --- a/src/DotNetCore.CAP.MongoDB/ICapPublisher.MongoDB.cs +++ b/src/DotNetCore.CAP.MongoDB/ICapPublisher.MongoDB.cs @@ -5,7 +5,7 @@ using System; using System.Threading; using System.Threading.Tasks; using DotNetCore.CAP.Abstractions; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using MongoDB.Driver; diff --git a/src/DotNetCore.CAP.MongoDB/IMonitoringApi.MongoDB.cs b/src/DotNetCore.CAP.MongoDB/IMonitoringApi.MongoDB.cs index 6bf0a26..3b022f2 100644 --- a/src/DotNetCore.CAP.MongoDB/IMonitoringApi.MongoDB.cs +++ b/src/DotNetCore.CAP.MongoDB/IMonitoringApi.MongoDB.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using DotNetCore.CAP.Dashboard; using DotNetCore.CAP.Dashboard.Monitoring; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; diff --git a/src/DotNetCore.CAP.MongoDB/IStorageConnection.MongoDB.cs b/src/DotNetCore.CAP.MongoDB/IStorageConnection.MongoDB.cs index 387e4c7..772ecb1 100644 --- a/src/DotNetCore.CAP.MongoDB/IStorageConnection.MongoDB.cs +++ b/src/DotNetCore.CAP.MongoDB/IStorageConnection.MongoDB.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; using MongoDB.Driver; diff --git a/src/DotNetCore.CAP.MongoDB/IStorageTransaction.MongoDB.cs b/src/DotNetCore.CAP.MongoDB/IStorageTransaction.MongoDB.cs index 1cbeff8..992aa8f 100644 --- a/src/DotNetCore.CAP.MongoDB/IStorageTransaction.MongoDB.cs +++ b/src/DotNetCore.CAP.MongoDB/IStorageTransaction.MongoDB.cs @@ -3,7 +3,7 @@ using System; using System.Threading.Tasks; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using MongoDB.Driver; namespace DotNetCore.CAP.MongoDB diff --git a/src/DotNetCore.CAP.MongoDB/StorageMessage.cs b/src/DotNetCore.CAP.MongoDB/StorageMessage.cs index b5abafa..ac253be 100644 --- a/src/DotNetCore.CAP.MongoDB/StorageMessage.cs +++ b/src/DotNetCore.CAP.MongoDB/StorageMessage.cs @@ -1,4 +1,4 @@ -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.MongoDB { diff --git a/src/DotNetCore.CAP.MySql/CAP.MySqlCapOptionsExtension.cs b/src/DotNetCore.CAP.MySql/CAP.MySqlCapOptionsExtension.cs index d9c7569..76aa126 100644 --- a/src/DotNetCore.CAP.MySql/CAP.MySqlCapOptionsExtension.cs +++ b/src/DotNetCore.CAP.MySql/CAP.MySqlCapOptionsExtension.cs @@ -3,7 +3,6 @@ using System; using DotNetCore.CAP.MySql; -using DotNetCore.CAP.Processor; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -22,12 +21,7 @@ namespace DotNetCore.CAP public void AddServices(IServiceCollection services) { services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(provider => (MySqlPublisher)provider.GetService()); - services.AddSingleton(); - + //services.AddSingleton(); services.AddTransient(); //Add MySqlOptions diff --git a/src/DotNetCore.CAP.MySql/ICapPublisher.MySql.cs b/src/DotNetCore.CAP.MySql/ICapPublisher.MySql.cs deleted file mode 100644 index ae67245..0000000 --- a/src/DotNetCore.CAP.MySql/ICapPublisher.MySql.cs +++ /dev/null @@ -1,66 +0,0 @@ -// 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.Data; -using System.Threading; -using System.Threading.Tasks; -using Dapper; -using DotNetCore.CAP.Abstractions; -using DotNetCore.CAP.Models; -using Microsoft.EntityFrameworkCore.Storage; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using MySql.Data.MySqlClient; - -namespace DotNetCore.CAP.MySql -{ - public class MySqlPublisher : CapPublisherBase, ICallbackPublisher - { - private readonly MySqlOptions _options; - - public MySqlPublisher(IServiceProvider provider) : base(provider) - { - _options = provider.GetService>().Value; - } - - public async Task PublishCallbackAsync(CapPublishedMessage message) - { - await PublishAsyncInternal(message); - } - - protected override async Task ExecuteAsync(CapPublishedMessage message, - ICapTransaction transaction = null, - CancellationToken cancel = default(CancellationToken)) - { - if (transaction == null) - { - using (var connection = new MySqlConnection(_options.ConnectionString)) - { - await connection.ExecuteAsync(PrepareSql(), message); - return; - } - } - - var dbTrans = transaction.DbTransaction as IDbTransaction; - if (dbTrans == null && transaction.DbTransaction is IDbContextTransaction dbContextTrans) - { - dbTrans = dbContextTrans.GetDbTransaction(); - } - - var conn = dbTrans?.Connection; - await conn.ExecuteAsync(PrepareSql(), message, dbTrans); - } - - #region private methods - - private string PrepareSql() - { - return - $"INSERT INTO `{_options.TableNamePrefix}.published` (`Id`,`Version`,`Name`,`Content`,`Retries`,`Added`,`ExpiresAt`,`StatusName`)" + - $"VALUES(@Id,'{_options.Version}',@Name,@Content,@Retries,@Added,@ExpiresAt,@StatusName);"; - } - - #endregion private methods - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP.MySql/ICapTransaction.MySql.cs b/src/DotNetCore.CAP.MySql/ICapTransaction.MySql.cs index 605b4cd..77f7919 100644 --- a/src/DotNetCore.CAP.MySql/ICapTransaction.MySql.cs +++ b/src/DotNetCore.CAP.MySql/ICapTransaction.MySql.cs @@ -3,7 +3,6 @@ using System.Data; using System.Diagnostics; -using System.Threading; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; diff --git a/src/DotNetCore.CAP.MySql/ICollectProcessor.MySql.cs b/src/DotNetCore.CAP.MySql/ICollectProcessor.MySql.cs deleted file mode 100644 index 55955c7..0000000 --- a/src/DotNetCore.CAP.MySql/ICollectProcessor.MySql.cs +++ /dev/null @@ -1,61 +0,0 @@ -// 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.Threading.Tasks; -using Dapper; -using DotNetCore.CAP.Processor; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using MySql.Data.MySqlClient; - -namespace DotNetCore.CAP.MySql -{ - internal class MySqlCollectProcessor : ICollectProcessor - { - private const int MaxBatch = 1000; - private readonly TimeSpan _delay = TimeSpan.FromSeconds(1); - private readonly ILogger _logger; - private readonly MySqlOptions _options; - private readonly TimeSpan _waitingInterval = TimeSpan.FromMinutes(5); - - public MySqlCollectProcessor(ILogger logger, IOptions mysqlOptions) - { - _logger = logger; - _options = mysqlOptions.Value; - } - - public async Task ProcessAsync(ProcessingContext context) - { - var tables = new[] - { - $"{_options.TableNamePrefix}.published", - $"{_options.TableNamePrefix}.received" - }; - - foreach (var table in tables) - { - _logger.LogDebug($"Collecting expired data from table [{table}]."); - - int removedCount; - do - { - using (var connection = new MySqlConnection(_options.ConnectionString)) - { - removedCount = await connection.ExecuteAsync( - $@"DELETE FROM `{table}` WHERE ExpiresAt < @now limit @count;", - new { now = DateTime.Now, count = MaxBatch }); - } - - if (removedCount != 0) - { - await context.WaitAsync(_delay); - context.ThrowIfStopping(); - } - } while (removedCount != 0); - } - - await context.WaitAsync(_waitingInterval); - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP.MySql/IMonitoringApi.MySql.cs b/src/DotNetCore.CAP.MySql/IMonitoringApi.MySql.cs index 7cd4135..ff5e491 100644 --- a/src/DotNetCore.CAP.MySql/IMonitoringApi.MySql.cs +++ b/src/DotNetCore.CAP.MySql/IMonitoringApi.MySql.cs @@ -1,194 +1,231 @@ -// 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.Collections.Generic; -using System.Data; -using System.Linq; -using Dapper; -using DotNetCore.CAP.Dashboard; -using DotNetCore.CAP.Dashboard.Monitoring; -using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; -using Microsoft.Extensions.Options; - -namespace DotNetCore.CAP.MySql -{ - internal class MySqlMonitoringApi : IMonitoringApi - { - private readonly string _prefix; - private readonly MySqlStorage _storage; - - public MySqlMonitoringApi(IStorage storage, IOptions options) - { - _storage = storage as MySqlStorage ?? throw new ArgumentNullException(nameof(storage)); - _prefix = options.Value.TableNamePrefix ?? throw new ArgumentNullException(nameof(options)); - } - - public StatisticsDto GetStatistics() - { - var sql = string.Format(@" -set transaction isolation level read committed; -select count(Id) from `{0}.published` where StatusName = N'Succeeded'; -select count(Id) from `{0}.received` where StatusName = N'Succeeded'; -select count(Id) from `{0}.published` where StatusName = N'Failed'; -select count(Id) from `{0}.received` where StatusName = N'Failed';", _prefix); - - var statistics = UseConnection(connection => - { - var stats = new StatisticsDto(); - using (var multi = connection.QueryMultiple(sql)) - { - stats.PublishedSucceeded = multi.ReadSingle(); - stats.ReceivedSucceeded = multi.ReadSingle(); - - stats.PublishedFailed = multi.ReadSingle(); - stats.ReceivedFailed = multi.ReadSingle(); - } - - return stats; - }); - return statistics; - } - - public IDictionary HourlyFailedJobs(MessageType type) - { - var tableName = type == MessageType.Publish ? "published" : "received"; - return UseConnection(connection => - GetHourlyTimelineStats(connection, tableName, StatusName.Failed)); - } - - public IDictionary HourlySucceededJobs(MessageType type) - { - var tableName = type == MessageType.Publish ? "published" : "received"; - return UseConnection(connection => - GetHourlyTimelineStats(connection, tableName, StatusName.Succeeded)); - } - - public IList Messages(MessageQueryDto queryDto) - { - var tableName = queryDto.MessageType == MessageType.Publish ? "published" : "received"; - var where = string.Empty; - if (!string.IsNullOrEmpty(queryDto.StatusName)) - { - where += " and StatusName=@StatusName"; - } - - if (!string.IsNullOrEmpty(queryDto.Name)) - { - where += " and Name=@Name"; - } - - if (!string.IsNullOrEmpty(queryDto.Group)) - { - where += " and `Group`=@Group"; - } - - if (!string.IsNullOrEmpty(queryDto.Content)) - { - where += " and Content like '%@Content%'"; - } - - var sqlQuery = - $"select * from `{_prefix}.{tableName}` where 1=1 {where} order by Added desc limit @Limit offset @Offset"; - - return UseConnection(conn => conn.Query(sqlQuery, new - { - queryDto.StatusName, - queryDto.Group, - queryDto.Name, - queryDto.Content, - Offset = queryDto.CurrentPage * queryDto.PageSize, - Limit = queryDto.PageSize - }).ToList()); - } - - public int PublishedFailedCount() - { - return UseConnection(conn => GetNumberOfMessage(conn, "published", StatusName.Failed)); - } - - public int PublishedSucceededCount() - { - return UseConnection(conn => GetNumberOfMessage(conn, "published", StatusName.Succeeded)); - } - - public int ReceivedFailedCount() - { - return UseConnection(conn => GetNumberOfMessage(conn, "received", StatusName.Failed)); - } - - public int ReceivedSucceededCount() - { - return UseConnection(conn => GetNumberOfMessage(conn, "received", StatusName.Succeeded)); - } - - private int GetNumberOfMessage(IDbConnection connection, string tableName, string statusName) - { - var sqlQuery = $"select count(Id) from `{_prefix}.{tableName}` where StatusName = @state"; - - var count = connection.ExecuteScalar(sqlQuery, new { state = statusName }); - return count; - } - - private T UseConnection(Func action) - { - return _storage.UseConnection(action); - } - - private Dictionary GetHourlyTimelineStats(IDbConnection connection, string tableName, - string statusName) - { - var endDate = DateTime.Now; - var dates = new List(); - for (var i = 0; i < 24; i++) - { - dates.Add(endDate); - endDate = endDate.AddHours(-1); - } - - var keyMaps = dates.ToDictionary(x => x.ToString("yyyy-MM-dd-HH"), x => x); - - return GetTimelineStats(connection, tableName, statusName, keyMaps); - } - - private Dictionary GetTimelineStats( - IDbConnection connection, - string tableName, - string statusName, - IDictionary keyMaps) - { - var sqlQuery = - $@" -select aggr.* from ( - select date_format(`Added`,'%Y-%m-%d-%H') as `Key`, - count(id) `Count` - from `{_prefix}.{tableName}` - where StatusName = @statusName - group by date_format(`Added`,'%Y-%m-%d-%H') -) aggr where `Key` in @keys;"; - - var valuesMap = connection.Query( - sqlQuery, - new { keys = keyMaps.Keys, statusName }) - .ToDictionary(x => x.Key, x => x.Count); - - foreach (var key in keyMaps.Keys) - { - if (!valuesMap.ContainsKey(key)) - { - valuesMap.Add(key, 0); - } - } - - var result = new Dictionary(); - for (var i = 0; i < keyMaps.Count; i++) - { - var value = valuesMap[keyMaps.ElementAt(i).Key]; - result.Add(keyMaps.ElementAt(i).Value, value); - } - - return result; - } - } -} \ No newline at end of file +//// 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.Collections.Generic; +//using System.Data; +//using System.Linq; +//using Dapper; +//using DotNetCore.CAP.Dashboard; +//using DotNetCore.CAP.Dashboard.Monitoring; +//using DotNetCore.CAP.Infrastructure; +//using DotNetCore.CAP.Messages; +//using Microsoft.Extensions.Options; +//using MySql.Data.MySqlClient; + +//namespace DotNetCore.CAP.MySql +//{ +// internal class MySqlMonitoringApi : IMonitoringApi +// { +// private readonly IDbConnection _existingConnection = null; +// private readonly string _prefix; +// private readonly string _connectionString; + +// public MySqlMonitoringApi(IOptions options) +// { +// _prefix = options.Value.TableNamePrefix ?? throw new ArgumentNullException(nameof(options)); +// _connectionString = options.Value.ConnectionString; +// } + +// public StatisticsDto GetStatistics() +// { +// var sql = string.Format(@" +//set transaction isolation level read committed; +//select count(Id) from `{0}.published` where StatusName = N'Succeeded'; +//select count(Id) from `{0}.received` where StatusName = N'Succeeded'; +//select count(Id) from `{0}.published` where StatusName = N'Failed'; +//select count(Id) from `{0}.received` where StatusName = N'Failed';", _prefix); + +// var statistics = UseConnection(connection => +// { +// var stats = new StatisticsDto(); +// using (var multi = connection.QueryMultiple(sql)) +// { +// stats.PublishedSucceeded = multi.ReadSingle(); +// stats.ReceivedSucceeded = multi.ReadSingle(); + +// stats.PublishedFailed = multi.ReadSingle(); +// stats.ReceivedFailed = multi.ReadSingle(); +// } + +// return stats; +// }); +// return statistics; +// } + +// public IDictionary HourlyFailedJobs(MessageType type) +// { +// var tableName = type == MessageType.Publish ? "published" : "received"; +// return UseConnection(connection => +// GetHourlyTimelineStats(connection, tableName, StatusName.Failed)); +// } + +// public IDictionary HourlySucceededJobs(MessageType type) +// { +// var tableName = type == MessageType.Publish ? "published" : "received"; +// return UseConnection(connection => +// GetHourlyTimelineStats(connection, tableName, StatusName.Succeeded)); +// } + +// public IList Messages(MessageQueryDto queryDto) +// { +// var tableName = queryDto.MessageType == MessageType.Publish ? "published" : "received"; +// var where = string.Empty; +// if (!string.IsNullOrEmpty(queryDto.StatusName)) +// { +// where += " and StatusName=@StatusName"; +// } + +// if (!string.IsNullOrEmpty(queryDto.Name)) +// { +// where += " and Name=@Name"; +// } + +// if (!string.IsNullOrEmpty(queryDto.Group)) +// { +// where += " and `Group`=@Group"; +// } + +// if (!string.IsNullOrEmpty(queryDto.Content)) +// { +// where += " and Content like '%@Content%'"; +// } + +// var sqlQuery = +// $"select * from `{_prefix}.{tableName}` where 1=1 {where} order by Added desc limit @Limit offset @Offset"; + +// return UseConnection(conn => conn.Query(sqlQuery, new +// { +// queryDto.StatusName, +// queryDto.Group, +// queryDto.Name, +// queryDto.Content, +// Offset = queryDto.CurrentPage * queryDto.PageSize, +// Limit = queryDto.PageSize +// }).ToList()); +// } + +// public int PublishedFailedCount() +// { +// return UseConnection(conn => GetNumberOfMessage(conn, "published", StatusName.Failed)); +// } + +// public int PublishedSucceededCount() +// { +// return UseConnection(conn => GetNumberOfMessage(conn, "published", StatusName.Succeeded)); +// } + +// public int ReceivedFailedCount() +// { +// return UseConnection(conn => GetNumberOfMessage(conn, "received", StatusName.Failed)); +// } + +// public int ReceivedSucceededCount() +// { +// return UseConnection(conn => GetNumberOfMessage(conn, "received", StatusName.Succeeded)); +// } + +// private int GetNumberOfMessage(IDbConnection connection, string tableName, string statusName) +// { +// var sqlQuery = $"select count(Id) from `{_prefix}.{tableName}` where StatusName = @state"; + +// var count = connection.ExecuteScalar(sqlQuery, new { state = statusName }); +// return count; +// } + +// private Dictionary GetHourlyTimelineStats(IDbConnection connection, string tableName, +// string statusName) +// { +// var endDate = DateTime.Now; +// var dates = new List(); +// for (var i = 0; i < 24; i++) +// { +// dates.Add(endDate); +// endDate = endDate.AddHours(-1); +// } + +// var keyMaps = dates.ToDictionary(x => x.ToString("yyyy-MM-dd-HH"), x => x); + +// return GetTimelineStats(connection, tableName, statusName, keyMaps); +// } + +// private Dictionary GetTimelineStats( +// IDbConnection connection, +// string tableName, +// string statusName, +// IDictionary keyMaps) +// { +// var sqlQuery = +// $@" +//select aggr.* from ( +// select date_format(`Added`,'%Y-%m-%d-%H') as `Key`, +// count(id) `Count` +// from `{_prefix}.{tableName}` +// where StatusName = @statusName +// group by date_format(`Added`,'%Y-%m-%d-%H') +//) aggr where `Key` in @keys;"; + +// var valuesMap = connection.Query( +// sqlQuery, +// new { keys = keyMaps.Keys, statusName }) +// .ToDictionary(x => x.Key, x => x.Count); + +// foreach (var key in keyMaps.Keys) +// { +// if (!valuesMap.ContainsKey(key)) +// { +// valuesMap.Add(key, 0); +// } +// } + +// var result = new Dictionary(); +// for (var i = 0; i < keyMaps.Count; i++) +// { +// var value = valuesMap[keyMaps.ElementAt(i).Key]; +// result.Add(keyMaps.ElementAt(i).Value, value); +// } + +// return result; +// } + +// private T UseConnection(Func func) +// { +// IDbConnection connection = null; + +// try +// { +// connection = CreateAndOpenConnection(); +// return func(connection); +// } +// finally +// { +// ReleaseConnection(connection); +// } +// } + +// private IDbConnection CreateAndOpenConnection() +// { +// var connection = _existingConnection ?? new MySqlConnection(_connectionString); + +// if (connection.State == ConnectionState.Closed) +// { +// connection.Open(); +// } + +// return connection; +// } + +// private bool IsExistingConnection(IDbConnection connection) +// { +// return connection != null && ReferenceEquals(connection, _existingConnection); +// } + +// private void ReleaseConnection(IDbConnection connection) +// { +// if (connection != null && !IsExistingConnection(connection)) +// { +// connection.Dispose(); +// } +// } +// } +//} \ No newline at end of file diff --git a/src/DotNetCore.CAP.MySql/IStorage.MySql.cs b/src/DotNetCore.CAP.MySql/IStorage.MySql.cs index 5be40b8..be84cc9 100644 --- a/src/DotNetCore.CAP.MySql/IStorage.MySql.cs +++ b/src/DotNetCore.CAP.MySql/IStorage.MySql.cs @@ -1,43 +1,38 @@ // 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.Data; using System.Threading; using System.Threading.Tasks; using Dapper; -using DotNetCore.CAP.Dashboard; +using DotNetCore.CAP.Persistence; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MySql.Data.MySqlClient; namespace DotNetCore.CAP.MySql { - public class MySqlStorage : IStorage + public class MySqlStorageInitializer : IStorageInitializer { - private readonly IOptions _capOptions; private readonly IOptions _options; - private readonly IDbConnection _existingConnection = null; private readonly ILogger _logger; - public MySqlStorage( - ILogger logger, + public MySqlStorageInitializer( + ILogger logger, IOptions options, IOptions capOptions) { _options = options; - _capOptions = capOptions; _logger = logger; } - public IStorageConnection GetConnection() + public string GetPublishedTableName() { - return new MySqlStorageConnection(_options, _capOptions); + return $"{_options.Value.TableNamePrefix}.published"; } - public IMonitoringApi GetMonitoringApi() + public string GetReceivedTableName() { - return new MySqlMonitoringApi(this, _options); + return $"{_options.Value.TableNamePrefix}.received"; } public async Task InitializeAsync(CancellationToken cancellationToken) @@ -56,6 +51,7 @@ namespace DotNetCore.CAP.MySql _logger.LogDebug("Ensuring all create database tables script are applied."); } + protected virtual string CreateDbTablesScript(string prefix) { var batchSql = @@ -87,45 +83,5 @@ CREATE TABLE IF NOT EXISTS `{prefix}.published` ( "; return batchSql; } - - internal T UseConnection(Func func) - { - IDbConnection connection = null; - - try - { - connection = CreateAndOpenConnection(); - return func(connection); - } - finally - { - ReleaseConnection(connection); - } - } - - internal IDbConnection CreateAndOpenConnection() - { - var connection = _existingConnection ?? new MySqlConnection(_options.Value.ConnectionString); - - if (connection.State == ConnectionState.Closed) - { - connection.Open(); - } - - return connection; - } - - internal bool IsExistingConnection(IDbConnection connection) - { - return connection != null && ReferenceEquals(connection, _existingConnection); - } - - internal void ReleaseConnection(IDbConnection connection) - { - if (connection != null && !IsExistingConnection(connection)) - { - connection.Dispose(); - } - } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP.MySql/IStorageConnection.MySql.cs b/src/DotNetCore.CAP.MySql/IStorageConnection.MySql.cs deleted file mode 100644 index 5f300bb..0000000 --- a/src/DotNetCore.CAP.MySql/IStorageConnection.MySql.cs +++ /dev/null @@ -1,116 +0,0 @@ -// 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.Collections.Generic; -using System.Threading.Tasks; -using Dapper; -using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; -using Microsoft.Extensions.Options; -using MySql.Data.MySqlClient; - -namespace DotNetCore.CAP.MySql -{ - public class MySqlStorageConnection : IStorageConnection - { - private readonly CapOptions _capOptions; - private readonly IOptions _options; - private readonly string _prefix; - - public MySqlStorageConnection(IOptions options, IOptions capOptions) - { - _options = options; - _capOptions = capOptions.Value; - _prefix = options.Value.TableNamePrefix; - } - - public MySqlOptions Options => _options.Value; - - public IStorageTransaction CreateTransaction() - { - return new MySqlStorageTransaction(this); - } - - public async Task GetPublishedMessageAsync(long id) - { - var sql = $@"SELECT * FROM `{_prefix}.published` WHERE `Id`={id};"; - - using (var connection = new MySqlConnection(Options.ConnectionString)) - { - return await connection.QueryFirstOrDefaultAsync(sql); - } - } - - public async Task> GetPublishedMessagesOfNeedRetry() - { - var fourMinsAgo = DateTime.Now.AddMinutes(-4).ToString("O"); - var sql = - $"SELECT * FROM `{_prefix}.published` WHERE `Retries`<{_capOptions.FailedRetryCount} AND `Version`='{_capOptions.Version}' AND `Added`<'{fourMinsAgo}' AND (`StatusName` = '{StatusName.Failed}' OR `StatusName` = '{StatusName.Scheduled}') LIMIT 200;"; - - using (var connection = new MySqlConnection(Options.ConnectionString)) - { - return await connection.QueryAsync(sql); - } - } - - public void StoreReceivedMessage(CapReceivedMessage message) - { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - var sql = $@" -INSERT INTO `{_prefix}.received`(`Id`,`Version`,`Name`,`Group`,`Content`,`Retries`,`Added`,`ExpiresAt`,`StatusName`) -VALUES(@Id,'{_capOptions.Version}',@Name,@Group,@Content,@Retries,@Added,@ExpiresAt,@StatusName);"; - - using (var connection = new MySqlConnection(Options.ConnectionString)) - { - connection.Execute(sql, message); - } - } - - public async Task GetReceivedMessageAsync(long id) - { - var sql = $@"SELECT * FROM `{_prefix}.received` WHERE Id={id};"; - using (var connection = new MySqlConnection(Options.ConnectionString)) - { - return await connection.QueryFirstOrDefaultAsync(sql); - } - } - - public async Task> GetReceivedMessagesOfNeedRetry() - { - var fourMinsAgo = DateTime.Now.AddMinutes(-4).ToString("O"); - var sql = - $"SELECT * FROM `{_prefix}.received` WHERE `Retries`<{_capOptions.FailedRetryCount} AND `Version`='{_capOptions.Version}' AND `Added`<'{fourMinsAgo}' AND (`StatusName` = '{StatusName.Failed}' OR `StatusName` = '{StatusName.Scheduled}') LIMIT 200;"; - using (var connection = new MySqlConnection(Options.ConnectionString)) - { - return await connection.QueryAsync(sql); - } - } - - public bool ChangePublishedState(long messageId, string state) - { - var sql = - $"UPDATE `{_prefix}.published` SET `Retries`=`Retries`+1,`ExpiresAt`=NULL,`StatusName` = '{state}' WHERE `Id`={messageId}"; - - using (var connection = new MySqlConnection(Options.ConnectionString)) - { - return connection.Execute(sql) > 0; - } - } - - public bool ChangeReceivedState(long messageId, string state) - { - var sql = - $"UPDATE `{_prefix}.received` SET `Retries`=`Retries`+1,`ExpiresAt`=NULL,`StatusName` = '{state}' WHERE `Id`={messageId}"; - - using (var connection = new MySqlConnection(Options.ConnectionString)) - { - return connection.Execute(sql) > 0; - } - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP.MySql/IStorageTransaction.MySql.cs b/src/DotNetCore.CAP.MySql/IStorageTransaction.MySql.cs deleted file mode 100644 index 44b77ab..0000000 --- a/src/DotNetCore.CAP.MySql/IStorageTransaction.MySql.cs +++ /dev/null @@ -1,63 +0,0 @@ -// 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.Data; -using System.Threading.Tasks; -using Dapper; -using DotNetCore.CAP.Models; -using MySql.Data.MySqlClient; - -namespace DotNetCore.CAP.MySql -{ - public class MySqlStorageTransaction : IStorageTransaction - { - private readonly IDbConnection _dbConnection; - - private readonly string _prefix; - - public MySqlStorageTransaction(MySqlStorageConnection connection) - { - var options = connection.Options; - _prefix = options.TableNamePrefix; - - _dbConnection = new MySqlConnection(options.ConnectionString); - } - - public void UpdateMessage(CapPublishedMessage message) - { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - var sql = - $"UPDATE `{_prefix}.published` SET `Retries` = @Retries,`Content`= @Content,`ExpiresAt` = @ExpiresAt,`StatusName`=@StatusName WHERE `Id`=@Id;"; - _dbConnection.Execute(sql, message); - } - - public void UpdateMessage(CapReceivedMessage message) - { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - var sql = - $"UPDATE `{_prefix}.received` SET `Retries` = @Retries,`Content`= @Content,`ExpiresAt` = @ExpiresAt,`StatusName`=@StatusName WHERE `Id`=@Id;"; - _dbConnection.Execute(sql, message); - } - - public Task CommitAsync() - { - _dbConnection.Close(); - _dbConnection.Dispose(); - return Task.CompletedTask; - } - - public void Dispose() - { - _dbConnection.Dispose(); - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP.MySql/MySqlDataStorage.cs b/src/DotNetCore.CAP.MySql/MySqlDataStorage.cs new file mode 100644 index 0000000..05f02aa --- /dev/null +++ b/src/DotNetCore.CAP.MySql/MySqlDataStorage.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Threading; +using System.Threading.Tasks; +using Dapper; +using DotNetCore.CAP.Infrastructure; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Persistence; +using DotNetCore.CAP.Serialization; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.Options; +using MySql.Data.MySqlClient; + +namespace DotNetCore.CAP.MySql +{ + public class MySqlDataStorage : IDataStorage + { + private readonly IOptions _options; + private readonly IOptions _capOptions; + + public MySqlDataStorage(IOptions options, IOptions capOptions) + { + _options = options; + _capOptions = capOptions; + } + + public async Task ChangePublishStateAsync(MediumMessage message, StatusName state) + { + using (var connection = new MySqlConnection(_options.Value.ConnectionString)) + { + var sql = $"UPDATE `{_options.Value.TableNamePrefix}.published` SET `Retries` = @Retries,`ExpiresAt` = @ExpiresAt,`StatusName`=@StatusName WHERE `Id`=@Id;"; + + await connection.ExecuteAsync(sql, new + { + Id = message.DbId, + Retries = message.Retries, + ExpiresAt = message.ExpiresAt, + StatusName = state.ToString("G") + }); + } + } + + public async Task ChangeReceiveStateAsync(MediumMessage message, StatusName state) + { + using (var connection = new MySqlConnection(_options.Value.ConnectionString)) + { + var sql = $"UPDATE `{_options.Value.TableNamePrefix}.received` SET `Retries` = @Retries,`ExpiresAt` = @ExpiresAt,`StatusName`=@StatusName WHERE `Id`=@Id;"; + + await connection.ExecuteAsync(sql, new + { + Id = message.DbId, + Retries = message.Retries, + ExpiresAt = message.ExpiresAt, + StatusName = state.ToString("G") + }); + } + } + + public async Task StoreMessageAsync(string name, Message content, object dbTransaction = null, CancellationToken cancellationToken = default) + { + var sql = $"INSERT INTO `{_options.Value.TableNamePrefix}.published`(`Id`,`Version`,`Name`,`Content`,`Retries`,`Added`,`ExpiresAt`,`StatusName`) VALUES(@Id,'{_options.Value.Version}',@Name,@Content,@Retries,@Added,@ExpiresAt,@StatusName);"; + + var message = new MediumMessage() + { + DbId = content.GetId(), + Origin = content, + Added = DateTime.Now, + ExpiresAt = null, + Retries = 0 + }; + + var po = new + { + Id = message.DbId, + Name = name, + Content = StringSerializer.Serialize(message.Origin), + Retries = message.Retries, + Added = message.Added, + ExpiresAt = message.ExpiresAt, + StatusName = StatusName.Scheduled + }; + + if (dbTransaction == null) + { + using (var connection = new MySqlConnection(_options.Value.ConnectionString)) + { + await connection.ExecuteAsync(sql, po); + } + } + else + { + var dbTrans = dbTransaction as IDbTransaction; + if (dbTrans == null && dbTransaction is IDbContextTransaction dbContextTrans) + { + dbTrans = dbContextTrans.GetDbTransaction(); + } + + var conn = dbTrans?.Connection; + await conn.ExecuteAsync(sql, po, dbTrans); + } + + return message; + } + + public async Task StoreMessageAsync(string name, string group, Message content, CancellationToken cancellationToken = default) + { + var sql = $@"INSERT INTO `{_options.Value.TableNamePrefix}.received`(`Id`,`Version`,`Name`,`Group`,`Content`,`Retries`,`Added`,`ExpiresAt`,`StatusName`) VALUES(@Id,'{_options.Value.Version}',@Name,@Group,@Content,@Retries,@Added,@ExpiresAt,@StatusName);"; + + var message = new MediumMessage() + { + DbId = SnowflakeId.Default().NextId().ToString(), + Origin = content, + Added = DateTime.Now, + ExpiresAt = null, + Retries = 0 + }; + + var po = new + { + Id = message.DbId, + Group = group, + Name = name, + Content = StringSerializer.Serialize(message.Origin), + Retries = message.Retries, + Added = message.Added, + ExpiresAt = message.ExpiresAt, + StatusName = StatusName.Scheduled + }; + + using (var connection = new MySqlConnection(_options.Value.ConnectionString)) + { + await connection.ExecuteAsync(sql, po); + } + return message; + } + + public async Task DeleteExpiresAsync(string table, DateTime timeout, int batchCount = 1000, CancellationToken token = default) + { + using (var connection = new MySqlConnection(_options.Value.ConnectionString)) + { + return await connection.ExecuteAsync( + $@"DELETE FROM `{table}` WHERE ExpiresAt < @timeout limit @batchCount;", + new { timeout, batchCount }); + } + } + + public async Task> GetPublishedMessagesOfNeedRetry() + { + var fourMinAgo = DateTime.Now.AddMinutes(-4).ToString("O"); + var sql = $"SELECT * FROM `{_options.Value.TableNamePrefix}.published` WHERE `Retries`<{_capOptions.Value.FailedRetryCount} AND `Version`='{_capOptions.Value.Version}' AND `Added`<'{fourMinAgo}' AND (`StatusName` = '{StatusName.Failed}' OR `StatusName` = '{StatusName.Scheduled}') LIMIT 200;"; + + var result = new List(); + using (var connection = new MySqlConnection(_options.Value.ConnectionString)) + { + var reader = await connection.ExecuteReaderAsync(sql); + while (reader.Read()) + { + result.Add(new MediumMessage() + { + DbId = reader.GetInt64(0).ToString(), + Origin = StringSerializer.DeSerialize(reader.GetString(3)), + Retries = reader.GetInt32(4), + Added = reader.GetDateTime(5) + }); + } + } + return result; + } + + public async Task> GetReceivedMessagesOfNeedRetry() + { + var fourMinAgo = DateTime.Now.AddMinutes(-4).ToString("O"); + var sql = + $"SELECT * FROM `{_options.Value.TableNamePrefix}.received` WHERE `Retries`<{_capOptions.Value.FailedRetryCount} AND `Version`='{_capOptions.Value.Version}' AND `Added`<'{fourMinAgo}' AND (`StatusName` = '{StatusName.Failed}' OR `StatusName` = '{StatusName.Scheduled}') LIMIT 200;"; + + var result = new List(); + using (var connection = new MySqlConnection(_options.Value.ConnectionString)) + { + var reader = await connection.ExecuteReaderAsync(sql); + while (reader.Read()) + { + result.Add(new MediumMessage() + { + DbId = reader.GetInt64(0).ToString(), + Origin = StringSerializer.DeSerialize(reader.GetString(3)), + Retries = reader.GetInt32(4), + Added = reader.GetDateTime(5) + }); + } + } + return result; + } + + //public Task GetPublishedMessageAsync(long id) + //{ + // var sql = $@"SELECT * FROM `{_prefix}.published` WHERE `Id`={id};"; + + // using (var connection = new MySqlConnection(Options.ConnectionString)) + // { + // return await connection.QueryFirstOrDefaultAsync(sql); + // } + //} + + //public Task GetReceivedMessageAsync(long id) + //{ + // var sql = + // $@"SELECT * FROM `{_prefix}.received` WHERE Id={id};"; + // using (var connection = new MySqlConnection(Options.ConnectionString)) + // { + // return await connection.QueryFirstOrDefaultAsync(sql); + // } + //} + } +} diff --git a/src/DotNetCore.CAP.PostgreSql/ICapPublisher.PostgreSql.cs b/src/DotNetCore.CAP.PostgreSql/ICapPublisher.PostgreSql.cs index 9c34b65..2631f7f 100644 --- a/src/DotNetCore.CAP.PostgreSql/ICapPublisher.PostgreSql.cs +++ b/src/DotNetCore.CAP.PostgreSql/ICapPublisher.PostgreSql.cs @@ -7,7 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Dapper; using DotNetCore.CAP.Abstractions; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; diff --git a/src/DotNetCore.CAP.PostgreSql/IMonitoringApi.PostgreSql.cs b/src/DotNetCore.CAP.PostgreSql/IMonitoringApi.PostgreSql.cs index 9760188..a2c3bcb 100644 --- a/src/DotNetCore.CAP.PostgreSql/IMonitoringApi.PostgreSql.cs +++ b/src/DotNetCore.CAP.PostgreSql/IMonitoringApi.PostgreSql.cs @@ -9,7 +9,7 @@ using Dapper; using DotNetCore.CAP.Dashboard; using DotNetCore.CAP.Dashboard.Monitoring; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; namespace DotNetCore.CAP.PostgreSql diff --git a/src/DotNetCore.CAP.PostgreSql/IStorageConnection.PostgreSql.cs b/src/DotNetCore.CAP.PostgreSql/IStorageConnection.PostgreSql.cs index afb3296..f2c0b5a 100644 --- a/src/DotNetCore.CAP.PostgreSql/IStorageConnection.PostgreSql.cs +++ b/src/DotNetCore.CAP.PostgreSql/IStorageConnection.PostgreSql.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Dapper; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; using Npgsql; diff --git a/src/DotNetCore.CAP.PostgreSql/IStorageTransaction.PostgreSql.cs b/src/DotNetCore.CAP.PostgreSql/IStorageTransaction.PostgreSql.cs index 28d75d8..44750eb 100644 --- a/src/DotNetCore.CAP.PostgreSql/IStorageTransaction.PostgreSql.cs +++ b/src/DotNetCore.CAP.PostgreSql/IStorageTransaction.PostgreSql.cs @@ -5,7 +5,7 @@ using System; using System.Data; using System.Threading.Tasks; using Dapper; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Npgsql; namespace DotNetCore.CAP.PostgreSql diff --git a/src/DotNetCore.CAP.RabbitMQ/CAP.RabbitMQCapOptionsExtension.cs b/src/DotNetCore.CAP.RabbitMQ/CAP.RabbitMQCapOptionsExtension.cs index ac1455a..4ed02f7 100644 --- a/src/DotNetCore.CAP.RabbitMQ/CAP.RabbitMQCapOptionsExtension.cs +++ b/src/DotNetCore.CAP.RabbitMQ/CAP.RabbitMQCapOptionsExtension.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Internal; using DotNetCore.CAP.RabbitMQ; using Microsoft.Extensions.DependencyInjection; @@ -24,8 +25,7 @@ namespace DotNetCore.CAP services.Configure(_configure); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP.RabbitMQ/IPublishMessageSender.RabbitMQ.cs b/src/DotNetCore.CAP.RabbitMQ/IPublishMessageSender.RabbitMQ.cs index ac4f2b9..2cb7efe 100644 --- a/src/DotNetCore.CAP.RabbitMQ/IPublishMessageSender.RabbitMQ.cs +++ b/src/DotNetCore.CAP.RabbitMQ/IPublishMessageSender.RabbitMQ.cs @@ -2,53 +2,50 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; -using System.Text; +using System.Linq; using System.Threading.Tasks; using DotNetCore.CAP.Internal; -using DotNetCore.CAP.Processor.States; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Transport; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; using RabbitMQ.Client; using RabbitMQ.Client.Framing; namespace DotNetCore.CAP.RabbitMQ { - internal sealed class RabbitMQPublishMessageSender : BasePublishMessageSender + internal sealed class RabbitMQMessageSender : ITransport { private readonly IConnectionChannelPool _connectionChannelPool; private readonly ILogger _logger; private readonly string _exchange; - public RabbitMQPublishMessageSender( - ILogger logger, - IOptions options, - IStorageConnection connection, - IConnectionChannelPool connectionChannelPool, - IStateChanger stateChanger) - : base(logger, options, connection, stateChanger) + public RabbitMQMessageSender( + ILogger logger, + IConnectionChannelPool connectionChannelPool) { _logger = logger; _connectionChannelPool = connectionChannelPool; _exchange = _connectionChannelPool.Exchange; } - protected override string ServersAddress => _connectionChannelPool.HostAddress; + public string Address => _connectionChannelPool.HostAddress; - public override Task PublishAsync(string keyName, string content) + public Task SendAsync(TransportMessage message) { var channel = _connectionChannelPool.Rent(); try { - var body = Encoding.UTF8.GetBytes(content); - var props = new BasicProperties() + var props = new BasicProperties { - DeliveryMode = 2 + DeliveryMode = 2, + Headers = message.Headers.ToDictionary(x => x.Key, x => (object)x.Value) }; channel.ExchangeDeclare(_exchange, RabbitMQOptions.ExchangeType, true); - channel.BasicPublish(_exchange, keyName, props, body); - _logger.LogDebug($"RabbitMQ topic message [{keyName}] has been published. Body: {content}"); + channel.BasicPublish(_exchange, message.GetName(), props, message.Body); + + _logger.LogDebug($"RabbitMQ topic message [{message.GetName()}] has been published."); return Task.FromResult(OperateResult.Success); } @@ -71,6 +68,6 @@ namespace DotNetCore.CAP.RabbitMQ channel.Dispose(); } } - } + } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP.RabbitMQ/RabbitMQConsumerClient.cs b/src/DotNetCore.CAP.RabbitMQ/RabbitMQConsumerClient.cs index 430ac20..94bf2cd 100644 --- a/src/DotNetCore.CAP.RabbitMQ/RabbitMQConsumerClient.cs +++ b/src/DotNetCore.CAP.RabbitMQ/RabbitMQConsumerClient.cs @@ -3,11 +3,13 @@ using System; using System.Collections.Generic; -using System.Text; +using System.Linq; using System.Threading; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; using RabbitMQ.Client; using RabbitMQ.Client.Events; +using Headers = DotNetCore.CAP.Messages.Headers; namespace DotNetCore.CAP.RabbitMQ { @@ -34,7 +36,7 @@ namespace DotNetCore.CAP.RabbitMQ _exchangeName = connectionChannelPool.Exchange; } - public event EventHandler OnMessageReceived; + public event EventHandler OnMessageReceived; public event EventHandler OnLog; @@ -125,7 +127,7 @@ namespace DotNetCore.CAP.RabbitMQ { _connectionLock.Release(); } - } + } private void OnConsumerConsumerCancelled(object sender, ConsumerEventArgs e) { @@ -160,12 +162,13 @@ namespace DotNetCore.CAP.RabbitMQ private void OnConsumerReceived(object sender, BasicDeliverEventArgs e) { _deliveryTag = e.DeliveryTag; - var message = new MessageContext - { - Group = _queueName, - Name = e.RoutingKey, - Content = Encoding.UTF8.GetString(e.Body) - }; + + var header = e.BasicProperties.Headers + .ToDictionary(x => x.Key, x => x.Value.ToString()); + header.Add(Headers.Group, _queueName); + + var message = new TransportMessage(header, e.Body); + OnMessageReceived?.Invoke(sender, message); } @@ -176,6 +179,7 @@ namespace DotNetCore.CAP.RabbitMQ LogType = MqLogType.ConsumerShutdown, Reason = e.ReplyText }; + OnLog?.Invoke(sender, args); } diff --git a/src/DotNetCore.CAP.SqlServer/Diagnostics/DiagnosticObserver.cs b/src/DotNetCore.CAP.SqlServer/Diagnostics/DiagnosticObserver.cs index 2f466fd..46d1b55 100644 --- a/src/DotNetCore.CAP.SqlServer/Diagnostics/DiagnosticObserver.cs +++ b/src/DotNetCore.CAP.SqlServer/Diagnostics/DiagnosticObserver.cs @@ -6,7 +6,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.SqlClient; using System.Reflection; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.SqlServer.Diagnostics { diff --git a/src/DotNetCore.CAP.SqlServer/Diagnostics/DiagnosticProcessorObserver.cs b/src/DotNetCore.CAP.SqlServer/Diagnostics/DiagnosticProcessorObserver.cs index 658f088..2e952a2 100644 --- a/src/DotNetCore.CAP.SqlServer/Diagnostics/DiagnosticProcessorObserver.cs +++ b/src/DotNetCore.CAP.SqlServer/Diagnostics/DiagnosticProcessorObserver.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.SqlServer.Diagnostics { diff --git a/src/DotNetCore.CAP.SqlServer/ICapPublisher.SqlServer.cs b/src/DotNetCore.CAP.SqlServer/ICapPublisher.SqlServer.cs index 7df28cf..59461eb 100644 --- a/src/DotNetCore.CAP.SqlServer/ICapPublisher.SqlServer.cs +++ b/src/DotNetCore.CAP.SqlServer/ICapPublisher.SqlServer.cs @@ -8,7 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Dapper; using DotNetCore.CAP.Abstractions; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; diff --git a/src/DotNetCore.CAP.SqlServer/ICapTransaction.SqlServer.cs b/src/DotNetCore.CAP.SqlServer/ICapTransaction.SqlServer.cs index c321801..006676b 100644 --- a/src/DotNetCore.CAP.SqlServer/ICapTransaction.SqlServer.cs +++ b/src/DotNetCore.CAP.SqlServer/ICapTransaction.SqlServer.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using DotNetCore.CAP.Internal; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using DotNetCore.CAP.SqlServer.Diagnostics; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; diff --git a/src/DotNetCore.CAP.SqlServer/IMonitoringApi.SqlServer.cs b/src/DotNetCore.CAP.SqlServer/IMonitoringApi.SqlServer.cs index d5498f2..a353c51 100644 --- a/src/DotNetCore.CAP.SqlServer/IMonitoringApi.SqlServer.cs +++ b/src/DotNetCore.CAP.SqlServer/IMonitoringApi.SqlServer.cs @@ -9,7 +9,7 @@ using Dapper; using DotNetCore.CAP.Dashboard; using DotNetCore.CAP.Dashboard.Monitoring; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; namespace DotNetCore.CAP.SqlServer diff --git a/src/DotNetCore.CAP.SqlServer/IStorageConnection.SqlServer.cs b/src/DotNetCore.CAP.SqlServer/IStorageConnection.SqlServer.cs index 72978a1..3ec78ed 100644 --- a/src/DotNetCore.CAP.SqlServer/IStorageConnection.SqlServer.cs +++ b/src/DotNetCore.CAP.SqlServer/IStorageConnection.SqlServer.cs @@ -7,7 +7,7 @@ using System.Data.SqlClient; using System.Threading.Tasks; using Dapper; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; namespace DotNetCore.CAP.SqlServer diff --git a/src/DotNetCore.CAP.SqlServer/IStorageTransaction.SqlServer.cs b/src/DotNetCore.CAP.SqlServer/IStorageTransaction.SqlServer.cs index d4d38f0..33fcce7 100644 --- a/src/DotNetCore.CAP.SqlServer/IStorageTransaction.SqlServer.cs +++ b/src/DotNetCore.CAP.SqlServer/IStorageTransaction.SqlServer.cs @@ -6,7 +6,7 @@ using System.Data; using System.Data.SqlClient; using System.Threading.Tasks; using Dapper; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.SqlServer { diff --git a/src/DotNetCore.CAP/Abstractions/CapPublisher.cs b/src/DotNetCore.CAP/Abstractions/CapPublisher.cs new file mode 100644 index 0000000..976ea8a --- /dev/null +++ b/src/DotNetCore.CAP/Abstractions/CapPublisher.cs @@ -0,0 +1,117 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using DotNetCore.CAP.Diagnostics; +using DotNetCore.CAP.Infrastructure; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Persistence; +using Microsoft.Extensions.DependencyInjection; + +namespace DotNetCore.CAP.Abstractions +{ + public class CapPublisher : ICapPublisher + { + private readonly IDispatcher _dispatcher; + private readonly IDataStorage _storage; + + // ReSharper disable once InconsistentNaming + protected static readonly DiagnosticListener s_diagnosticListener = + new DiagnosticListener(CapDiagnosticListenerExtensions.DiagnosticListenerName); + + protected CapPublisher(IServiceProvider service) + { + ServiceProvider = service; + _dispatcher = service.GetRequiredService(); + _storage = service.GetRequiredService(); + Transaction = new AsyncLocal(); + } + + public IServiceProvider ServiceProvider { get; } + + public AsyncLocal Transaction { get; } + + public async Task PublishAsync(string name, T value, + IDictionary optionHeaders, + CancellationToken cancellationToken = default) + { + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + + if (optionHeaders == null) + { + optionHeaders = new Dictionary(); + } + + var messageId = SnowflakeId.Default().NextId().ToString(); + optionHeaders.Add(Headers.MessageId, messageId); + if (!optionHeaders.ContainsKey(Headers.CorrelationId)) + { + optionHeaders.Add(Headers.CorrelationId, messageId); + optionHeaders.Add(Headers.CorrelationSequence, 0.ToString()); + } + optionHeaders.Add(Headers.MessageName, name); + optionHeaders.Add(Headers.Type, typeof(T).ToString()); + optionHeaders.Add(Headers.SentTime, DateTimeOffset.Now.ToString()); + + var message = new Message(optionHeaders, value); + + var operationId = default(Guid); + try + { + operationId = s_diagnosticListener.WritePublishMessageStoreBefore(message); + + if (Transaction.Value?.DbTransaction == null) + { + var mediumMessage = await _storage.StoreMessageAsync(name, message, cancellationToken: cancellationToken); + + s_diagnosticListener.WritePublishMessageStoreAfter(operationId, message); + + _dispatcher.EnqueueToPublish(mediumMessage); + } + else + { + var transaction = (CapTransactionBase)Transaction.Value; + + var mediumMessage = await _storage.StoreMessageAsync(name, message, transaction, cancellationToken); + + s_diagnosticListener.WritePublishMessageStoreAfter(operationId, message); + + transaction.AddToSent(mediumMessage); + + if (transaction.AutoCommit) + { + transaction.Commit(); + } + } + } + catch (Exception e) + { + s_diagnosticListener.WritePublishMessageStoreError(operationId, message, e); + throw; + } + } + + public void Publish(string name, T value, string callbackName = null) + { + PublishAsync(name, value, callbackName).GetAwaiter().GetResult(); + } + + public Task PublishAsync(string name, T value, string callbackName = null, + CancellationToken cancellationToken = default) + { + var header = new Dictionary + { + {Headers.CallbackName, callbackName} + }; + + return PublishAsync(name, value, header, cancellationToken); + } + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Abstractions/CapPublisherBase.cs b/src/DotNetCore.CAP/Abstractions/CapPublisherBase.cs deleted file mode 100644 index 90665fd..0000000 --- a/src/DotNetCore.CAP/Abstractions/CapPublisherBase.cs +++ /dev/null @@ -1,128 +0,0 @@ -// 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.Diagnostics; -using System.Threading; -using System.Threading.Tasks; -using DotNetCore.CAP.Diagnostics; -using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; -using Microsoft.Extensions.DependencyInjection; - -namespace DotNetCore.CAP.Abstractions -{ - public abstract class CapPublisherBase : ICapPublisher - { - private readonly IMessagePacker _msgPacker; - private readonly IContentSerializer _serializer; - private readonly IDispatcher _dispatcher; - - // ReSharper disable once InconsistentNaming - protected static readonly DiagnosticListener s_diagnosticListener = - new DiagnosticListener(CapDiagnosticListenerExtensions.DiagnosticListenerName); - - protected CapPublisherBase(IServiceProvider service) - { - ServiceProvider = service; - _dispatcher = service.GetRequiredService(); - _msgPacker = service.GetRequiredService(); - _serializer = service.GetRequiredService(); - Transaction = new AsyncLocal(); - } - - public IServiceProvider ServiceProvider { get; } - - public AsyncLocal Transaction { get; } - - public void Publish(string name, T contentObj, string callbackName = null) - { - var message = new CapPublishedMessage - { - Id = SnowflakeId.Default().NextId(), - Name = name, - Content = Serialize(contentObj, callbackName), - StatusName = StatusName.Scheduled - }; - - PublishAsyncInternal(message).GetAwaiter().GetResult(); - } - - public async Task PublishAsync(string name, T contentObj, string callbackName = null, - CancellationToken cancellationToken = default(CancellationToken)) - { - var message = new CapPublishedMessage - { - Id = SnowflakeId.Default().NextId(), - Name = name, - Content = Serialize(contentObj, callbackName), - StatusName = StatusName.Scheduled - }; - - await PublishAsyncInternal(message); - } - - protected async Task PublishAsyncInternal(CapPublishedMessage message) - { - var operationId = default(Guid); - - try - { - operationId = s_diagnosticListener.WritePublishMessageStoreBefore(message); - - if (Transaction.Value?.DbTransaction == null) - { - await ExecuteAsync(message); - - s_diagnosticListener.WritePublishMessageStoreAfter(operationId, message); - - _dispatcher.EnqueueToPublish(message); - } - else - { - var transaction = (CapTransactionBase)Transaction.Value; - - await ExecuteAsync(message, transaction); - - s_diagnosticListener.WritePublishMessageStoreAfter(operationId, message); - - transaction.AddToSent(message); - if (transaction.AutoCommit) - { - transaction.Commit(); - } - } - } - catch (Exception e) - { - s_diagnosticListener.WritePublishMessageStoreError(operationId, message, e); - - throw; - } - } - - protected abstract Task ExecuteAsync(CapPublishedMessage message, - ICapTransaction transaction = null, - CancellationToken cancel = default(CancellationToken)); - - protected virtual string Serialize(T obj, string callbackName = null) - { - string content; - if (obj != null) - { - content = Helper.IsComplexType(obj.GetType()) - ? _serializer.Serialize(obj) - : obj.ToString(); - } - else - { - content = string.Empty; - } - var message = new CapMessageDto(content) - { - CallbackName = callbackName - }; - return _msgPacker.Pack(message); - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Abstractions/IContentSerializer.cs b/src/DotNetCore.CAP/Abstractions/IContentSerializer.cs index 108f975..d225dd3 100644 --- a/src/DotNetCore.CAP/Abstractions/IContentSerializer.cs +++ b/src/DotNetCore.CAP/Abstractions/IContentSerializer.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Abstractions { diff --git a/src/DotNetCore.CAP/CAP.AppBuilderExtensions.cs b/src/DotNetCore.CAP/CAP.AppBuilderExtensions.cs index 7d15d0b..035d295 100644 --- a/src/DotNetCore.CAP/CAP.AppBuilderExtensions.cs +++ b/src/DotNetCore.CAP/CAP.AppBuilderExtensions.cs @@ -3,8 +3,6 @@ using System; using DotNetCore.CAP; -using DotNetCore.CAP.Dashboard.GatewayProxy; -using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; // ReSharper disable once CheckNamespace @@ -20,29 +18,29 @@ namespace Microsoft.AspNetCore.Builder /// /// The instance this method extends. /// The instance this method extends. - public static IApplicationBuilder UseCapDashboard(this IApplicationBuilder app) - { - if (app == null) - { - throw new ArgumentNullException(nameof(app)); - } + //public static IApplicationBuilder UseCapDashboard(this IApplicationBuilder app) + //{ + // if (app == null) + // { + // throw new ArgumentNullException(nameof(app)); + // } - CheckRequirement(app); + // CheckRequirement(app); - var provider = app.ApplicationServices; + // var provider = app.ApplicationServices; - if (provider.GetService() != null) - { - if (provider.GetService() != null) - { - app.UseMiddleware(); - } + // if (provider.GetService() != null) + // { + // if (provider.GetService() != null) + // { + // app.UseMiddleware(); + // } - app.UseMiddleware(); - } + // app.UseMiddleware(); + // } - return app; - } + // return app; + //} private static void CheckRequirement(IApplicationBuilder app) { @@ -69,16 +67,16 @@ namespace Microsoft.AspNetCore.Builder } } - sealed class CapStartupFilter : IStartupFilter - { - public Action Configure(Action next) - { - return app => - { - app.UseCapDashboard(); + //sealed class CapStartupFilter : IStartupFilter + //{ + // public Action Configure(Action next) + // { + // return app => + // { + // app.UseCapDashboard(); - next(app); - }; - } - } + // next(app); + // }; + // } + //} } \ No newline at end of file diff --git a/src/DotNetCore.CAP/CAP.Options.cs b/src/DotNetCore.CAP/CAP.Options.cs index 13a3af4..ea178d1 100644 --- a/src/DotNetCore.CAP/CAP.Options.cs +++ b/src/DotNetCore.CAP/CAP.Options.cs @@ -4,7 +4,8 @@ using System; using System.Collections.Generic; using System.Reflection; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; + // ReSharper disable InconsistentNaming namespace DotNetCore.CAP @@ -52,7 +53,7 @@ namespace DotNetCore.CAP /// /// We’ll invoke this call-back with message type,name,content when retry failed (send or executed) messages equals times. /// - public Action FailedThresholdCallback { get; set; } + public Action FailedThresholdCallback { get; set; } /// /// The number of message retries, the retry will stop when the threshold is reached. diff --git a/src/DotNetCore.CAP/CAP.ServiceCollectionExtensions.cs b/src/DotNetCore.CAP/CAP.ServiceCollectionExtensions.cs index c28743d..f349455 100644 --- a/src/DotNetCore.CAP/CAP.ServiceCollectionExtensions.cs +++ b/src/DotNetCore.CAP/CAP.ServiceCollectionExtensions.cs @@ -6,7 +6,6 @@ using DotNetCore.CAP; using DotNetCore.CAP.Abstractions; using DotNetCore.CAP.Internal; using DotNetCore.CAP.Processor; -using DotNetCore.CAP.Processor.States; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -44,7 +43,7 @@ namespace Microsoft.Extensions.DependencyInjection services.TryAddSingleton(); services.TryAddSingleton(); - services.TryAddSingleton(); + //services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); @@ -53,13 +52,13 @@ namespace Microsoft.Extensions.DependencyInjection services.TryAddEnumerable(ServiceDescriptor.Singleton()); services.TryAddEnumerable(ServiceDescriptor.Singleton()); - services.TryAddSingleton(); //Queue's message processor services.TryAddSingleton(); services.TryAddSingleton(); //Sender and Executors + services.AddSingleton(); services.TryAddSingleton(); // Warning: IPublishMessageSender need to inject at extension project. services.TryAddSingleton(); @@ -74,7 +73,7 @@ namespace Microsoft.Extensions.DependencyInjection services.Configure(setupAction); //Startup and Hosted - services.AddTransient(); + //services.AddTransient(); services.AddHostedService(); return new CapBuilder(services); diff --git a/src/DotNetCore.CAP/Diagnostics/DiagnosticListenerExtensions.cs b/src/DotNetCore.CAP/Diagnostics/DiagnosticListenerExtensions.cs index da0cc0c..0016a4d 100644 --- a/src/DotNetCore.CAP/Diagnostics/DiagnosticListenerExtensions.cs +++ b/src/DotNetCore.CAP/Diagnostics/DiagnosticListenerExtensions.cs @@ -4,8 +4,7 @@ using System; using System.Diagnostics; using System.Runtime.CompilerServices; -using DotNetCore.CAP.Internal; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Diagnostics { @@ -18,28 +17,28 @@ namespace DotNetCore.CAP.Diagnostics private const string CapPrefix = "DotNetCore.CAP."; - public const string CapBeforePublishMessageStore = CapPrefix + nameof(WritePublishMessageStoreBefore); - public const string CapAfterPublishMessageStore = CapPrefix + nameof(WritePublishMessageStoreAfter); - public const string CapErrorPublishMessageStore = CapPrefix + nameof(WritePublishMessageStoreError); + public const string CapBeforePublishMessageStore = CapPrefix + "WritePublishMessageStoreBefore"; + public const string CapAfterPublishMessageStore = CapPrefix + "WritePublishMessageStoreAfter"; + public const string CapErrorPublishMessageStore = CapPrefix + "WritePublishMessageStoreError"; - public const string CapBeforePublish = CapPrefix + nameof(WritePublishBefore); - public const string CapAfterPublish = CapPrefix + nameof(WritePublishAfter); - public const string CapErrorPublish = CapPrefix + nameof(WritePublishError); + public const string CapBeforePublish = CapPrefix + "WritePublishBefore"; + public const string CapAfterPublish = CapPrefix + "WritePublishAfter"; + public const string CapErrorPublish = CapPrefix + "WritePublishError"; - public const string CapBeforeConsume = CapPrefix + nameof(WriteConsumeBefore); - public const string CapAfterConsume = CapPrefix + nameof(WriteConsumeAfter); - public const string CapErrorConsume = CapPrefix + nameof(WriteConsumeError); + public const string CapBeforeConsume = CapPrefix + "WriteConsumeBefore"; + public const string CapAfterConsume = CapPrefix + "WriteConsumeAfter"; + public const string CapErrorConsume = CapPrefix + "WriteConsumeError"; - public const string CapBeforeSubscriberInvoke = CapPrefix + nameof(WriteSubscriberInvokeBefore); - public const string CapAfterSubscriberInvoke = CapPrefix + nameof(WriteSubscriberInvokeAfter); - public const string CapErrorSubscriberInvoke = CapPrefix + nameof(WriteSubscriberInvokeError); + public const string CapBeforeSubscriberInvoke = CapPrefix + "WriteSubscriberInvokeBefore"; + public const string CapAfterSubscriberInvoke = CapPrefix + "WriteSubscriberInvokeAfter"; + public const string CapErrorSubscriberInvoke = CapPrefix + "WriteSubscriberInvokeError"; //============================================================================ //==================== Before publish store message ==================== //============================================================================ public static Guid WritePublishMessageStoreBefore(this DiagnosticListener @this, - CapPublishedMessage message, + Message message, [CallerMemberName] string operation = "") { if (@this.IsEnabled(CapBeforePublishMessageStore)) @@ -50,8 +49,7 @@ namespace DotNetCore.CAP.Diagnostics { OperationId = operationId, Operation = operation, - MessageName = message.Name, - MessageContent = message.Content + Message = message }); return operationId; @@ -62,7 +60,7 @@ namespace DotNetCore.CAP.Diagnostics public static void WritePublishMessageStoreAfter(this DiagnosticListener @this, Guid operationId, - CapPublishedMessage message, + Message message, [CallerMemberName] string operation = "") { if (@this.IsEnabled(CapAfterPublishMessageStore)) @@ -71,9 +69,7 @@ namespace DotNetCore.CAP.Diagnostics { OperationId = operationId, Operation = operation, - MessageId = message.Id, - MessageName = message.Name, - MessageContent = message.Content, + Message = message, Timestamp = Stopwatch.GetTimestamp() }); } @@ -81,7 +77,7 @@ namespace DotNetCore.CAP.Diagnostics public static void WritePublishMessageStoreError(this DiagnosticListener @this, Guid operationId, - CapPublishedMessage message, + Message message, Exception ex, [CallerMemberName] string operation = "") { @@ -91,8 +87,7 @@ namespace DotNetCore.CAP.Diagnostics { OperationId = operationId, Operation = operation, - MessageName = message.Name, - MessageContent = message.Content, + Message = message, Exception = ex, Timestamp = Stopwatch.GetTimestamp() }); @@ -100,135 +95,135 @@ namespace DotNetCore.CAP.Diagnostics } - //============================================================================ - //==================== Publish ==================== - //============================================================================ - public static void WritePublishBefore(this DiagnosticListener @this, BrokerPublishEventData eventData) - { - if (@this.IsEnabled(CapBeforePublish)) - { - eventData.Headers = new TracingHeaders(); - @this.Write(CapBeforePublish, eventData); - } - } - - public static void WritePublishAfter(this DiagnosticListener @this, BrokerPublishEndEventData eventData) - { - if (@this.IsEnabled(CapAfterPublish)) - { - eventData.Headers = new TracingHeaders(); - @this.Write(CapAfterPublish, eventData); - } - } - - public static void WritePublishError(this DiagnosticListener @this, BrokerPublishErrorEventData eventData) - { - if (@this.IsEnabled(CapErrorPublish)) - { - eventData.Headers = new TracingHeaders(); - @this.Write(CapErrorPublish, eventData); - } - } + ////============================================================================ + ////==================== Publish ==================== + ////============================================================================ + //public static void WritePublishBefore(this DiagnosticListener @this, BrokerPublishEventData eventData) + //{ + // if (@this.IsEnabled(CapBeforePublish)) + // { + // eventData.Headers = new TracingHeaders(); + // @this.Write(CapBeforePublish, eventData); + // } + //} + + //public static void WritePublishAfter(this DiagnosticListener @this, BrokerPublishEndEventData eventData) + //{ + // if (@this.IsEnabled(CapAfterPublish)) + // { + // eventData.Headers = new TracingHeaders(); + // @this.Write(CapAfterPublish, eventData); + // } + //} + + //public static void WritePublishError(this DiagnosticListener @this, BrokerPublishErrorEventData eventData) + //{ + // if (@this.IsEnabled(CapErrorPublish)) + // { + // eventData.Headers = new TracingHeaders(); + // @this.Write(CapErrorPublish, eventData); + // } + //} //============================================================================ //==================== Consume ==================== //============================================================================ - public static Guid WriteConsumeBefore(this DiagnosticListener @this, BrokerConsumeEventData eventData) - { - if (@this.IsEnabled(CapBeforeConsume)) - { - eventData.Headers = new TracingHeaders(); - @this.Write(CapBeforeConsume, eventData); - } - - return Guid.Empty; - } - - public static void WriteConsumeAfter(this DiagnosticListener @this, BrokerConsumeEndEventData eventData) - { - if (@this.IsEnabled(CapAfterConsume)) - { - eventData.Headers = new TracingHeaders(); - @this.Write(CapAfterConsume, eventData); - } - } - - public static void WriteConsumeError(this DiagnosticListener @this, BrokerConsumeErrorEventData eventData) - { - if (@this.IsEnabled(CapErrorConsume)) - { - eventData.Headers = new TracingHeaders(); - @this.Write(CapErrorConsume, eventData); - } - } + //public static Guid WriteConsumeBefore(this DiagnosticListener @this, BrokerConsumeEventData eventData) + //{ + // if (@this.IsEnabled(CapBeforeConsume)) + // { + // eventData.Headers = new TracingHeaders(); + // @this.Write(CapBeforeConsume, eventData); + // } + + // return Guid.Empty; + //} + + //public static void WriteConsumeAfter(this DiagnosticListener @this, BrokerConsumeEndEventData eventData) + //{ + // if (@this.IsEnabled(CapAfterConsume)) + // { + // eventData.Headers = new TracingHeaders(); + // @this.Write(CapAfterConsume, eventData); + // } + //} + + //public static void WriteConsumeError(this DiagnosticListener @this, BrokerConsumeErrorEventData eventData) + //{ + // if (@this.IsEnabled(CapErrorConsume)) + // { + // eventData.Headers = new TracingHeaders(); + // @this.Write(CapErrorConsume, eventData); + // } + //} //============================================================================ //==================== SubscriberInvoke ==================== //============================================================================ - public static Guid WriteSubscriberInvokeBefore(this DiagnosticListener @this, - ConsumerContext context, - [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(CapBeforeSubscriberInvoke)) - { - var operationId = Guid.NewGuid(); - - var methodName = context.ConsumerDescriptor.MethodInfo.Name; - var subscribeName = context.ConsumerDescriptor.Attribute.Name; - var subscribeGroup = context.ConsumerDescriptor.Attribute.Group; - var parameterValues = context.DeliverMessage.Content; - - @this.Write(CapBeforeSubscriberInvoke, new SubscriberInvokeEventData(operationId, operation, methodName, - subscribeName, - subscribeGroup, parameterValues, DateTimeOffset.UtcNow)); - - return operationId; - } - - return Guid.Empty; - } - - public static void WriteSubscriberInvokeAfter(this DiagnosticListener @this, - Guid operationId, - ConsumerContext context, - DateTimeOffset startTime, - TimeSpan duration, - [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(CapAfterSubscriberInvoke)) - { - var methodName = context.ConsumerDescriptor.MethodInfo.Name; - var subscribeName = context.ConsumerDescriptor.Attribute.Name; - var subscribeGroup = context.ConsumerDescriptor.Attribute.Group; - var parameterValues = context.DeliverMessage.Content; - - @this.Write(CapAfterSubscriberInvoke, new SubscriberInvokeEndEventData(operationId, operation, methodName, - subscribeName, - subscribeGroup, parameterValues, startTime, duration)); - } - } - - public static void WriteSubscriberInvokeError(this DiagnosticListener @this, - Guid operationId, - ConsumerContext context, - Exception ex, - DateTimeOffset startTime, - TimeSpan duration, - [CallerMemberName] string operation = "") - { - if (@this.IsEnabled(CapErrorSubscriberInvoke)) - { - var methodName = context.ConsumerDescriptor.MethodInfo.Name; - var subscribeName = context.ConsumerDescriptor.Attribute.Name; - var subscribeGroup = context.ConsumerDescriptor.Attribute.Group; - var parameterValues = context.DeliverMessage.Content; - - @this.Write(CapErrorSubscriberInvoke, new SubscriberInvokeErrorEventData(operationId, operation, methodName, - subscribeName, - subscribeGroup, parameterValues, ex, startTime, duration)); - } - } + //public static Guid WriteSubscriberInvokeBefore(this DiagnosticListener @this, + // ConsumerContext context, + // [CallerMemberName] string operation = "") + //{ + // if (@this.IsEnabled(CapBeforeSubscriberInvoke)) + // { + // var operationId = Guid.NewGuid(); + + // var methodName = context.ConsumerDescriptor.MethodInfo.Name; + // var subscribeName = context.ConsumerDescriptor.Attribute.Name; + // var subscribeGroup = context.ConsumerDescriptor.Attribute.Group; + // var values = context.DeliverMessage.Value; + + // @this.Write(CapBeforeSubscriberInvoke, new SubscriberInvokeEventData(operationId, operation, methodName, + // subscribeName, + // subscribeGroup, parameterValues, DateTimeOffset.UtcNow)); + + // return operationId; + // } + + // return Guid.Empty; + //} + + //public static void WriteSubscriberInvokeAfter(this DiagnosticListener @this, + // Guid operationId, + // ConsumerContext context, + // DateTimeOffset startTime, + // TimeSpan duration, + // [CallerMemberName] string operation = "") + //{ + // if (@this.IsEnabled(CapAfterSubscriberInvoke)) + // { + // var methodName = context.ConsumerDescriptor.MethodInfo.Name; + // var subscribeName = context.ConsumerDescriptor.Attribute.Name; + // var subscribeGroup = context.ConsumerDescriptor.Attribute.Group; + // var values = context.DeliverMessage.Value; + + // @this.Write(CapAfterSubscriberInvoke, new SubscriberInvokeEndEventData(operationId, operation, methodName, + // subscribeName, + // subscribeGroup, parameterValues, startTime, duration)); + // } + //} + + //public static void WriteSubscriberInvokeError(this DiagnosticListener @this, + // Guid operationId, + // ConsumerContext context, + // Exception ex, + // DateTimeOffset startTime, + // TimeSpan duration, + // [CallerMemberName] string operation = "") + //{ + // if (@this.IsEnabled(CapErrorSubscriberInvoke)) + // { + // var methodName = context.ConsumerDescriptor.MethodInfo.Name; + // var subscribeName = context.ConsumerDescriptor.Attribute.Name; + // var subscribeGroup = context.ConsumerDescriptor.Attribute.Group; + // var parameterValues = context.DeliverMessage.Content; + + // @this.Write(CapErrorSubscriberInvoke, new SubscriberInvokeErrorEventData(operationId, operation, methodName, + // subscribeName, + // subscribeGroup, parameterValues, ex, startTime, duration)); + // } + //} } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.Consume.cs b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.Consume.cs index b24b01a..177dcf2 100644 --- a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.Consume.cs +++ b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.Consume.cs @@ -2,18 +2,26 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Diagnostics { - public class BrokerConsumeEventData : BrokerEventData + public class BrokerConsumeEventData { - public BrokerConsumeEventData(Guid operationId, string operation, string brokerAddress, - string brokerTopicName, string brokerTopicBody, DateTimeOffset startTime) - : base(operationId, operation, brokerAddress, brokerTopicName, brokerTopicBody) + public BrokerConsumeEventData(Guid operationId,string brokerAddress, TransportMessage message, DateTimeOffset startTime) { + OperationId = operationId; StartTime = startTime; + BrokerAddress = brokerAddress; + Message = message; } + public Guid OperationId { get; set; } + + public string BrokerAddress { get; set; } + + public TransportMessage Message { get; set; } + public DateTimeOffset StartTime { get; } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.ConsumeEnd.cs b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.ConsumeEnd.cs index 013eace..135998c 100644 --- a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.ConsumeEnd.cs +++ b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.ConsumeEnd.cs @@ -2,15 +2,14 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Diagnostics { public class BrokerConsumeEndEventData : BrokerConsumeEventData { - public BrokerConsumeEndEventData(Guid operationId, string operation, string brokerAddress, - string brokerTopicName, - string brokerTopicBody, DateTimeOffset startTime, TimeSpan duration) - : base(operationId, operation, brokerAddress, brokerTopicName, brokerTopicBody, startTime) + public BrokerConsumeEndEventData(Guid operationId, string operation, string brokerAddress, TransportMessage message, DateTimeOffset startTime, TimeSpan duration) + : base(operationId, brokerAddress, message, startTime) { Duration = duration; } diff --git a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.ConsumeError.cs b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.ConsumeError.cs index 36af350..f6c17b4 100644 --- a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.ConsumeError.cs +++ b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.ConsumeError.cs @@ -2,19 +2,26 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Diagnostics { - public class BrokerConsumeErrorEventData : BrokerConsumeEndEventData, IErrorEventData + public class BrokerConsumeErrorEventData : IErrorEventData { - public BrokerConsumeErrorEventData(Guid operationId, string operation, string brokerAddress, - string brokerTopicName, string brokerTopicBody, Exception exception, DateTimeOffset startTime, - TimeSpan duration) - : base(operationId, operation, brokerAddress, brokerTopicName, brokerTopicBody, startTime, duration) + public BrokerConsumeErrorEventData(Guid operationId, string brokerAddress, TransportMessage message, Exception exception) { + OperationId = operationId; + BrokerAddress = brokerAddress; + Message = message; Exception = exception; } + public Guid OperationId { get; set; } + + public string BrokerAddress { get; } + + public TransportMessage Message { get; } + public Exception Exception { get; } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.Publish.cs b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.Publish.cs index 320f956..56b43e9 100644 --- a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.Publish.cs +++ b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.Publish.cs @@ -2,14 +2,15 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Diagnostics { public class BrokerPublishEventData : BrokerEventData { public BrokerPublishEventData(Guid operationId, string operation, string brokerAddress, - string brokerTopicName, string brokerTopicBody, DateTimeOffset startTime) - : base(operationId, operation, brokerAddress, brokerTopicName, brokerTopicBody) + Message message , DateTimeOffset startTime) + : base(operationId, operation, brokerAddress, message) { StartTime = startTime; } diff --git a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.PublishEnd.cs b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.PublishEnd.cs index bc3d0cb..6286dfc 100644 --- a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.PublishEnd.cs +++ b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.PublishEnd.cs @@ -2,15 +2,15 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Diagnostics { public class BrokerPublishEndEventData : BrokerPublishEventData { public BrokerPublishEndEventData(Guid operationId, string operation, string brokerAddress, - string brokerTopicName, - string brokerTopicBody, DateTimeOffset startTime, TimeSpan duration) - : base(operationId, operation, brokerAddress, brokerTopicName, brokerTopicBody, startTime) + Message message, DateTimeOffset startTime, TimeSpan duration) + : base(operationId, operation, brokerAddress, message, startTime) { Duration = duration; } diff --git a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.PublishError.cs b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.PublishError.cs index ec44e3b..fbf561a 100644 --- a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.PublishError.cs +++ b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.PublishError.cs @@ -2,15 +2,15 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Diagnostics { public class BrokerPublishErrorEventData : BrokerPublishEndEventData, IErrorEventData { public BrokerPublishErrorEventData(Guid operationId, string operation, string brokerAddress, - string brokerTopicName, string brokerTopicBody, Exception exception, DateTimeOffset startTime, - TimeSpan duration) - : base(operationId, operation, brokerAddress, brokerTopicName, brokerTopicBody, startTime, duration) + Message message, Exception exception, DateTimeOffset startTime, TimeSpan duration) + : base(operationId, operation, brokerAddress, message, startTime, duration) { Exception = exception; } diff --git a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.cs b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.cs index 2db1794..77a41b1 100644 --- a/src/DotNetCore.CAP/Diagnostics/EventData.Broker.cs +++ b/src/DotNetCore.CAP/Diagnostics/EventData.Broker.cs @@ -2,26 +2,22 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Diagnostics { public class BrokerEventData : EventData { - public BrokerEventData(Guid operationId, string operation, string brokerAddress, - string brokerTopicName, string brokerTopicBody) + public BrokerEventData(Guid operationId, string operation, string brokerAddress, Message message) : base(operationId, operation) { BrokerAddress = brokerAddress; - BrokerTopicName = brokerTopicName; - BrokerTopicBody = brokerTopicBody; - } - public TracingHeaders Headers { get; set; } + Message = message; + } public string BrokerAddress { get; set; } - public string BrokerTopicBody { get; set; } - - public string BrokerTopicName { get; set; } + public Message Message { get; set; } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Diagnostics/EventData.SubscriberInvoke.cs b/src/DotNetCore.CAP/Diagnostics/EventData.SubscriberInvoke.cs index 2302eec..f3c5cb0 100644 --- a/src/DotNetCore.CAP/Diagnostics/EventData.SubscriberInvoke.cs +++ b/src/DotNetCore.CAP/Diagnostics/EventData.SubscriberInvoke.cs @@ -12,14 +12,13 @@ namespace DotNetCore.CAP.Diagnostics string methodName, string subscribeName, string subscribeGroup, - string parameterValues, + object values, DateTimeOffset startTime) : base(operationId, operation) { MethodName = methodName; SubscribeName = subscribeName; SubscribeGroup = subscribeGroup; - ParameterValues = parameterValues; StartTime = startTime; } @@ -31,6 +30,6 @@ namespace DotNetCore.CAP.Diagnostics public string SubscribeGroup { get; set; } - public string ParameterValues { get; set; } + public string Values { get; set; } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/DotNetCore.CAP.csproj b/src/DotNetCore.CAP/DotNetCore.CAP.csproj index 892d42d..61a59bd 100644 --- a/src/DotNetCore.CAP/DotNetCore.CAP.csproj +++ b/src/DotNetCore.CAP/DotNetCore.CAP.csproj @@ -9,27 +9,6 @@ 1701;1702;1705;CS1591 - - - - - - - - - - - - - - - - - - - - - @@ -37,88 +16,7 @@ - - - - True - True - Strings.resx - - - _SidebarMenu.cshtml - - - _SidebarMenu.cshtml - - - ReceivedPage.cshtml - - - ReceivedPage.cshtml - - - _BlockMetric.cshtml - - - _BlockMetric.cshtml - - - _Breadcrumbs.cshtml - - - _Breadcrumbs.cshtml - - - _Paginator.cshtml - - - _Paginator.cshtml - - - _PerPageSelector.cshtml - - - _PerPageSelector.cshtml - - - PublishedPage.cshtml - - - PublishedPage.cshtml - - - LayoutPage.cshtml - - - LayoutPage.cshtml - - - _InlineMetric.cshtml - - - _InlineMetric.cshtml - - - _Navigation.cshtml - - - HomePage.cshtml - - - HomePage.cshtml - - - SubscriberPage.cshtml - - - NodePage.cshtml - - - - PublicResXFileCodeGenerator - DotNetCore.CAP.Dashboard.Resources - Strings.Designer.cs - + \ No newline at end of file diff --git a/src/DotNetCore.CAP/IBootstrapper.Default.cs b/src/DotNetCore.CAP/IBootstrapper.Default.cs index 87a56c0..f580efa 100644 --- a/src/DotNetCore.CAP/IBootstrapper.Default.cs +++ b/src/DotNetCore.CAP/IBootstrapper.Default.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using DotNetCore.CAP.Persistence; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -19,7 +20,7 @@ namespace DotNetCore.CAP public DefaultBootstrapper( ILogger logger, - IStorage storage, + IStorageInitializer storage, IEnumerable processors) { _logger = logger; @@ -27,7 +28,7 @@ namespace DotNetCore.CAP Processors = processors; } - private IStorage Storage { get; } + private IStorageInitializer Storage { get; } private IEnumerable Processors { get; } diff --git a/src/DotNetCore.CAP/ICallbackPublisher.cs b/src/DotNetCore.CAP/ICallbackPublisher.cs index e92e6c9..01d8920 100644 --- a/src/DotNetCore.CAP/ICallbackPublisher.cs +++ b/src/DotNetCore.CAP/ICallbackPublisher.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System.Threading.Tasks; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP { diff --git a/src/DotNetCore.CAP/ICapPublisher.cs b/src/DotNetCore.CAP/ICapPublisher.cs index dacfb42..e6f5ef2 100644 --- a/src/DotNetCore.CAP/ICapPublisher.cs +++ b/src/DotNetCore.CAP/ICapPublisher.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -26,7 +27,10 @@ namespace DotNetCore.CAP /// message body content, that will be serialized of json. /// callback subscriber name /// - Task PublishAsync(string name, T contentObj, string callbackName = null, CancellationToken cancellationToken = default(CancellationToken)); + Task PublishAsync(string name, T contentObj, string callbackName = null, CancellationToken cancellationToken = default); + + + Task PublishAsync(string name, T contentObj, IDictionary optionHeaders, CancellationToken cancellationToken = default); /// /// Publish an object message. diff --git a/src/DotNetCore.CAP/ICapTransaction.Base.cs b/src/DotNetCore.CAP/ICapTransaction.Base.cs index 2ad69b0..6f5c623 100644 --- a/src/DotNetCore.CAP/ICapTransaction.Base.cs +++ b/src/DotNetCore.CAP/ICapTransaction.Base.cs @@ -1,5 +1,5 @@ using System.Collections.Concurrent; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Persistence; namespace DotNetCore.CAP { @@ -7,19 +7,19 @@ namespace DotNetCore.CAP { private readonly IDispatcher _dispatcher; - private readonly ConcurrentQueue _bufferList; + private readonly ConcurrentQueue _bufferList; protected CapTransactionBase(IDispatcher dispatcher) { _dispatcher = dispatcher; - _bufferList = new ConcurrentQueue(); + _bufferList = new ConcurrentQueue(); } public bool AutoCommit { get; set; } public object DbTransaction { get; set; } - protected internal virtual void AddToSent(CapPublishedMessage msg) + protected internal virtual void AddToSent(MediumMessage msg) { _bufferList.Enqueue(msg); } @@ -29,6 +29,7 @@ namespace DotNetCore.CAP while (!_bufferList.IsEmpty) { _bufferList.TryDequeue(out var message); + _dispatcher.EnqueueToPublish(message); } } diff --git a/src/DotNetCore.CAP/IConsumerClient.cs b/src/DotNetCore.CAP/IConsumerClient.cs index 150bc4c..b918fc8 100644 --- a/src/DotNetCore.CAP/IConsumerClient.cs +++ b/src/DotNetCore.CAP/IConsumerClient.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Threading; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP { @@ -36,7 +37,7 @@ namespace DotNetCore.CAP /// void Reject(); - event EventHandler OnMessageReceived; + event EventHandler OnMessageReceived; event EventHandler OnLog; } diff --git a/src/DotNetCore.CAP/IConsumerRegister.Default.cs b/src/DotNetCore.CAP/IConsumerRegister.Default.cs index 22bf989..5e86511 100644 --- a/src/DotNetCore.CAP/IConsumerRegister.Default.cs +++ b/src/DotNetCore.CAP/IConsumerRegister.Default.cs @@ -7,9 +7,10 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using DotNetCore.CAP.Diagnostics; -using DotNetCore.CAP.Infrastructure; using DotNetCore.CAP.Internal; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Persistence; +using DotNetCore.CAP.Serialization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -17,9 +18,10 @@ namespace DotNetCore.CAP { internal class ConsumerRegister : IConsumerRegister { - private readonly IStorageConnection _connection; private readonly IConsumerClientFactory _consumerClientFactory; private readonly IDispatcher _dispatcher; + private readonly ISerializer _serializer; + private readonly IDataStorage _storage; private readonly ILogger _logger; private readonly TimeSpan _pollingDelay = TimeSpan.FromSeconds(1); private readonly CapOptions _options; @@ -40,7 +42,8 @@ namespace DotNetCore.CAP IOptions options, IConsumerClientFactory consumerClientFactory, IDispatcher dispatcher, - IStorageConnection connection, + ISerializer serializer, + IDataStorage storage, ILogger logger, MethodMatcherCache selector) { @@ -49,7 +52,8 @@ namespace DotNetCore.CAP _logger = logger; _consumerClientFactory = consumerClientFactory; _dispatcher = dispatcher; - _connection = connection; + _serializer = serializer; + _storage = storage; _cts = new CancellationTokenSource(); } @@ -144,34 +148,28 @@ namespace DotNetCore.CAP private void RegisterMessageProcessor(IConsumerClient client) { - client.OnMessageReceived += (sender, messageContext) => + client.OnMessageReceived += async (sender, messageContext) => { _cts.Token.ThrowIfCancellationRequested(); - - var startTime = DateTimeOffset.UtcNow; - var stopwatch = Stopwatch.StartNew(); - - var tracingResult = TracingBefore(messageContext.Name, messageContext.Content); - var operationId = tracingResult.Item1; - var messageBody = tracingResult.Item2; - - var receivedMessage = new CapReceivedMessage(messageContext) - { - Id = SnowflakeId.Default().NextId(), - StatusName = StatusName.Scheduled, - Content = messageBody - }; - + Guid? operationId = null; try { - StoreMessage(receivedMessage); + operationId = TracingBefore(messageContext); + + var startTime = DateTimeOffset.UtcNow; + var stopwatch = Stopwatch.StartNew(); + + var message = await _serializer.DeserializeAsync(messageContext); + var mediumMessage = await _storage.StoreMessageAsync(message.GetName(), message.GetGroup(), message); client.Commit(); - TracingAfter(operationId, receivedMessage.Name, receivedMessage.Content, startTime, - stopwatch.Elapsed); + if (operationId != null) + { + TracingAfter(operationId.Value, message, startTime, stopwatch.Elapsed); + } - _dispatcher.EnqueueToExecute(receivedMessage); + _dispatcher.EnqueueToExecute(mediumMessage); } catch (Exception e) { @@ -179,8 +177,10 @@ namespace DotNetCore.CAP client.Reject(); - TracingError(operationId, receivedMessage.Name, receivedMessage.Content, e, startTime, - stopwatch.Elapsed); + if (operationId != null) + { + TracingError(operationId.Value, messageContext, e); + } } }; @@ -217,56 +217,39 @@ namespace DotNetCore.CAP } } - private void StoreMessage(CapReceivedMessage receivedMessage) + private Guid? TracingBefore(TransportMessage message) { - _connection.StoreReceivedMessage(receivedMessage); - } - - private (Guid, string) TracingBefore(string topic, string values) - { - _logger.LogDebug("CAP received topic message:" + topic); + if (s_diagnosticListener.IsEnabled(CapDiagnosticListenerExtensions.CapBeforeConsume)) + { + var operationId = Guid.NewGuid(); - Guid operationId = Guid.NewGuid(); + var eventData = new BrokerConsumeEventData(operationId, _serverAddress, message, DateTimeOffset.UtcNow); - var eventData = new BrokerConsumeEventData( - operationId, "", - _serverAddress, - topic, - values, - DateTimeOffset.UtcNow); + s_diagnosticListener.Write(CapDiagnosticListenerExtensions.CapBeforeConsume, eventData); - s_diagnosticListener.WriteConsumeBefore(eventData); + return operationId; + } - return (operationId, eventData.BrokerTopicBody); + return null; } - private void TracingAfter(Guid operationId, string topic, string values, DateTimeOffset startTime, TimeSpan du) + private void TracingAfter(Guid operationId, Message message, DateTimeOffset startTime, TimeSpan du) { - var eventData = new BrokerConsumeEndEventData( - operationId, - "", - _serverAddress, - topic, - values, - startTime, - du); - - s_diagnosticListener.WriteConsumeAfter(eventData); + //if (s_diagnosticListener.IsEnabled(CapDiagnosticListenerExtensions.CapAfterConsume)) + //{ + // var eventData = new BrokerConsumeEndEventData(operationId, "", _serverAddress, message, startTime, du); + + // s_diagnosticListener.Write(CapDiagnosticListenerExtensions.CapAfterConsume, eventData); + //} } - private void TracingError(Guid operationId, string topic, string values, Exception ex, DateTimeOffset startTime, TimeSpan du) + private void TracingError(Guid operationId, TransportMessage message, Exception ex) { - var eventData = new BrokerConsumeErrorEventData( - operationId, - "", - _serverAddress, - topic, - values, - ex, - startTime, - du); - - s_diagnosticListener.WriteConsumeError(eventData); + if (s_diagnosticListener.IsEnabled(CapDiagnosticListenerExtensions.CapErrorConsume)) + { + var eventData = new BrokerConsumeErrorEventData(operationId, _serverAddress, message, ex); + s_diagnosticListener.Write(CapDiagnosticListenerExtensions.CapErrorConsume, eventData); + } } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/IDispatcher.cs b/src/DotNetCore.CAP/IDispatcher.cs index e8553ea..c56a582 100644 --- a/src/DotNetCore.CAP/IDispatcher.cs +++ b/src/DotNetCore.CAP/IDispatcher.cs @@ -1,14 +1,15 @@ // 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.Models; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Persistence; namespace DotNetCore.CAP { public interface IDispatcher { - void EnqueueToPublish(CapPublishedMessage message); + void EnqueueToPublish(MediumMessage message); - void EnqueueToExecute(CapReceivedMessage message); + void EnqueueToExecute(MediumMessage message); } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/IPublishExecutor.cs b/src/DotNetCore.CAP/IPublishExecutor.cs deleted file mode 100644 index 3997273..0000000 --- a/src/DotNetCore.CAP/IPublishExecutor.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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.Threading.Tasks; - -namespace DotNetCore.CAP -{ - /// - /// publish message excutor. The excutor sends the message to the message queue - /// - public interface IPublishExecutor - { - /// - /// publish message to message queue. - /// - /// The message topic name. - /// The message content. - /// - Task PublishAsync(string keyName, string content); - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/IPublishMessageSender.Base.cs b/src/DotNetCore.CAP/IPublishMessageSender.Base.cs deleted file mode 100644 index 873929f..0000000 --- a/src/DotNetCore.CAP/IPublishMessageSender.Base.cs +++ /dev/null @@ -1,198 +0,0 @@ -// 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.Diagnostics; -using System.Threading.Tasks; -using DotNetCore.CAP.Diagnostics; -using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Internal; -using DotNetCore.CAP.Models; -using DotNetCore.CAP.Processor; -using DotNetCore.CAP.Processor.States; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace DotNetCore.CAP -{ - public abstract class BasePublishMessageSender : IPublishMessageSender, IPublishExecutor - { - private readonly IStorageConnection _connection; - private readonly ILogger _logger; - private readonly CapOptions _options; - private readonly IStateChanger _stateChanger; - - protected abstract string ServersAddress { get; } - - // diagnostics listener - // ReSharper disable once InconsistentNaming - protected static readonly DiagnosticListener s_diagnosticListener = - new DiagnosticListener(CapDiagnosticListenerExtensions.DiagnosticListenerName); - - protected BasePublishMessageSender( - ILogger logger, - IOptions options, - IStorageConnection connection, - IStateChanger stateChanger) - { - _options = options.Value; - _connection = connection; - _stateChanger = stateChanger; - _logger = logger; - } - - public abstract Task PublishAsync(string keyName, string content); - - public async Task SendAsync(CapPublishedMessage message) - { - bool retry; - OperateResult result; - do - { - var executedResult = await SendWithoutRetryAsync(message); - result = executedResult.Item2; - if (result == OperateResult.Success) - { - return result; - } - retry = executedResult.Item1; - } while (retry); - - return result; - } - - private async Task<(bool, OperateResult)> SendWithoutRetryAsync(CapPublishedMessage message) - { - var startTime = DateTimeOffset.UtcNow; - var stopwatch = Stopwatch.StartNew(); - - var tracingResult = TracingBefore(message.Name, message.Content); - var operationId = tracingResult.Item1; - - var sendValues = tracingResult.Item2 != null - ? Helper.AddTracingHeaderProperty(message.Content, tracingResult.Item2) - : message.Content; - - var result = await PublishAsync(message.Name, sendValues); - - stopwatch.Stop(); - if (result.Succeeded) - { - await SetSuccessfulState(message); - - TracingAfter(operationId, message.Name, sendValues, startTime, stopwatch.Elapsed); - - return (false, OperateResult.Success); - } - else - { - TracingError(operationId, message, result, startTime, stopwatch.Elapsed); - - var needRetry = await SetFailedState(message, result.Exception); - return (needRetry, OperateResult.Failed(result.Exception)); - } - } - - - private Task SetSuccessfulState(CapPublishedMessage message) - { - var succeededState = new SucceededState(_options.SucceedMessageExpiredAfter); - return _stateChanger.ChangeStateAsync(message, succeededState, _connection); - } - - private async Task SetFailedState(CapPublishedMessage message, Exception ex) - { - AddErrorReasonToContent(message, ex); - - var needRetry = UpdateMessageForRetry(message); - - await _stateChanger.ChangeStateAsync(message, new FailedState(), _connection); - - return needRetry; - } - - private static void AddErrorReasonToContent(CapPublishedMessage message, Exception exception) - { - message.Content = Helper.AddExceptionProperty(message.Content, exception); - } - - private bool UpdateMessageForRetry(CapPublishedMessage message) - { - var retryBehavior = RetryBehavior.DefaultRetry; - - var retries = ++message.Retries; - message.ExpiresAt = message.Added.AddSeconds(retryBehavior.RetryIn(retries)); - - var retryCount = Math.Min(_options.FailedRetryCount, retryBehavior.RetryCount); - if (retries >= retryCount) - { - if (retries == _options.FailedRetryCount) - { - try - { - _options.FailedThresholdCallback?.Invoke(MessageType.Subscribe, message.Name, message.Content); - - _logger.SenderAfterThreshold(message.Id, _options.FailedRetryCount); - } - catch (Exception ex) - { - _logger.ExecutedThresholdCallbackFailed(ex); - } - } - return false; - } - - _logger.SenderRetrying(message.Id, retries); - - return true; - } - - private (Guid, TracingHeaders) TracingBefore(string topic, string values) - { - Guid operationId = Guid.NewGuid(); - - var eventData = new BrokerPublishEventData( - operationId, "", - ServersAddress, topic, - values, - DateTimeOffset.UtcNow); - - s_diagnosticListener.WritePublishBefore(eventData); - - return (operationId, eventData.Headers); //if not enabled diagnostics ,the header will be null - } - - private void TracingAfter(Guid operationId, string topic, string values, DateTimeOffset startTime, TimeSpan du) - { - var eventData = new BrokerPublishEndEventData( - operationId, - "", - ServersAddress, - topic, - values, - startTime, - du); - - s_diagnosticListener.WritePublishAfter(eventData); - } - - private void TracingError(Guid operationId, CapPublishedMessage message, OperateResult result, DateTimeOffset startTime, TimeSpan du) - { - var ex = new PublisherSentFailedException(result.ToString(), result.Exception); - - _logger.MessagePublishException(message.Id, result.ToString(), ex); - - var eventData = new BrokerPublishErrorEventData( - operationId, - "", - ServersAddress, - message.Name, - message.Content, - ex, - startTime, - du); - - s_diagnosticListener.WritePublishError(eventData); - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/IPublishMessageSender.cs b/src/DotNetCore.CAP/IPublishMessageSender.cs deleted file mode 100644 index c99afd8..0000000 --- a/src/DotNetCore.CAP/IPublishMessageSender.cs +++ /dev/null @@ -1,13 +0,0 @@ -// 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.Threading.Tasks; -using DotNetCore.CAP.Models; - -namespace DotNetCore.CAP -{ - public interface IPublishMessageSender - { - Task SendAsync(CapPublishedMessage message); - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/IStorage.cs b/src/DotNetCore.CAP/IStorage.cs deleted file mode 100644 index a31b351..0000000 --- a/src/DotNetCore.CAP/IStorage.cs +++ /dev/null @@ -1,30 +0,0 @@ -// 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.Threading; -using System.Threading.Tasks; -using DotNetCore.CAP.Dashboard; - -namespace DotNetCore.CAP -{ - /// - /// Represents a persisted storage. - /// - public interface IStorage - { - /// - /// Initializes the storage. For example, making sure a database is created and migrations are applied. - /// - Task InitializeAsync(CancellationToken cancellationToken); - - /// - /// Provider the dashboard metric api. - /// - IMonitoringApi GetMonitoringApi(); - - /// - /// Storage connection of database operate. - /// - IStorageConnection GetConnection(); - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/IStorageConnection.cs b/src/DotNetCore.CAP/IStorageConnection.cs index ba9b413..5ce8d9e 100644 --- a/src/DotNetCore.CAP/IStorageConnection.cs +++ b/src/DotNetCore.CAP/IStorageConnection.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Threading.Tasks; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP { @@ -44,10 +44,6 @@ namespace DotNetCore.CAP /// Task> GetReceivedMessagesOfNeedRetry(); - /// - /// Creates and returns an . - /// - IStorageTransaction CreateTransaction(); /// /// Change specified message's state of published message diff --git a/src/DotNetCore.CAP/IStorageTransaction.cs b/src/DotNetCore.CAP/IStorageTransaction.cs deleted file mode 100644 index 7ee5185..0000000 --- a/src/DotNetCore.CAP/IStorageTransaction.cs +++ /dev/null @@ -1,22 +0,0 @@ -// 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.Threading.Tasks; -using DotNetCore.CAP.Models; - -namespace DotNetCore.CAP -{ - /// - /// A transactional database storage operation. - /// Update message state of the message table with transactional. - /// - public interface IStorageTransaction : IDisposable - { - void UpdateMessage(CapPublishedMessage message); - - void UpdateMessage(CapReceivedMessage message); - - Task CommitAsync(); - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/ISubscribeExecutor.Default.cs b/src/DotNetCore.CAP/ISubscribeExecutor.Default.cs index 19ecbc9..2694098 100644 --- a/src/DotNetCore.CAP/ISubscribeExecutor.Default.cs +++ b/src/DotNetCore.CAP/ISubscribeExecutor.Default.cs @@ -2,15 +2,16 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using DotNetCore.CAP.Diagnostics; using DotNetCore.CAP.Infrastructure; using DotNetCore.CAP.Internal; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Persistence; using DotNetCore.CAP.Processor; -using DotNetCore.CAP.Processor.States; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -18,10 +19,9 @@ namespace DotNetCore.CAP { internal class DefaultSubscriberExecutor : ISubscriberExecutor { - private readonly ICallbackMessageSender _callbackMessageSender; - private readonly IStorageConnection _connection; + private readonly ICapPublisher _sender; + private readonly IDataStorage _dataStorage; private readonly ILogger _logger; - private readonly IStateChanger _stateChanger; private readonly CapOptions _options; private readonly MethodMatcherCache _selector; @@ -34,16 +34,14 @@ namespace DotNetCore.CAP ILogger logger, IOptions options, IConsumerInvokerFactory consumerInvokerFactory, - ICallbackMessageSender callbackMessageSender, - IStateChanger stateChanger, - IStorageConnection connection, + ICapPublisher sender, + IDataStorage dataStorage, MethodMatcherCache selector) { _selector = selector; - _callbackMessageSender = callbackMessageSender; + _sender = sender; _options = options.Value; - _stateChanger = stateChanger; - _connection = connection; + _dataStorage = dataStorage; _logger = logger; Invoker = consumerInvokerFactory.CreateInvoker(); @@ -51,7 +49,7 @@ namespace DotNetCore.CAP private IConsumerInvoker Invoker { get; } - public async Task ExecuteAsync(CapReceivedMessage message, CancellationToken cancellationToken) + public async Task ExecuteAsync(MediumMessage message, CancellationToken cancellationToken) { bool retry; OperateResult result; @@ -69,13 +67,7 @@ namespace DotNetCore.CAP return result; } - /// - /// Execute message consumption once. - /// - /// the message received of - /// - /// Item1 is need still retry, Item2 is executed result. - private async Task<(bool, OperateResult)> ExecuteWithoutRetryAsync(CapReceivedMessage message, CancellationToken cancellationToken) + private async Task<(bool, OperateResult)> ExecuteWithoutRetryAsync(MediumMessage message, CancellationToken cancellationToken) { if (message == null) { @@ -100,35 +92,36 @@ namespace DotNetCore.CAP } catch (Exception ex) { - _logger.LogError(ex, $"An exception occurred while executing the subscription method. Topic:{message.Name}, Id:{message.Id}"); + _logger.LogError(ex, $"An exception occurred while executing the subscription method. Topic:{message.Origin.GetName()}, Id:{message.DbId}"); return (await SetFailedState(message, ex), OperateResult.Failed(ex)); } } - private Task SetSuccessfulState(CapReceivedMessage message) + private Task SetSuccessfulState(MediumMessage message) { - var succeededState = new SucceededState(_options.SucceedMessageExpiredAfter); - return _stateChanger.ChangeStateAsync(message, succeededState, _connection); + message.ExpiresAt = DateTime.Now.AddSeconds(_options.SucceedMessageExpiredAfter); + return _dataStorage.ChangeReceiveStateAsync(message, StatusName.Succeeded); } - private async Task SetFailedState(CapReceivedMessage message, Exception ex) + private async Task SetFailedState(MediumMessage message, Exception ex) { if (ex is SubscriberNotFoundException) { message.Retries = _options.FailedRetryCount; // not retry if SubscriberNotFoundException } - AddErrorReasonToContent(message, ex); + //TODO: Add exception to content + // AddErrorReasonToContent(message, ex); var needRetry = UpdateMessageForRetry(message); - await _stateChanger.ChangeStateAsync(message, new FailedState(), _connection); + await _dataStorage.ChangeReceiveStateAsync(message, StatusName.Failed); return needRetry; } - private bool UpdateMessageForRetry(CapReceivedMessage message) + private bool UpdateMessageForRetry(MediumMessage message) { var retryBehavior = RetryBehavior.DefaultRetry; @@ -142,9 +135,9 @@ namespace DotNetCore.CAP { try { - _options.FailedThresholdCallback?.Invoke(MessageType.Subscribe, message.Name, message.Content); + _options.FailedThresholdCallback?.Invoke(MessageType.Subscribe, message.Origin); - _logger.ConsumerExecutedAfterThreshold(message.Id, _options.FailedRetryCount); + _logger.ConsumerExecutedAfterThreshold(message.DbId, _options.FailedRetryCount); } catch (Exception ex) { @@ -154,22 +147,24 @@ namespace DotNetCore.CAP return false; } - _logger.ConsumerExecutionRetrying(message.Id, retries); + _logger.ConsumerExecutionRetrying(message.DbId, retries); return true; } - private static void AddErrorReasonToContent(CapReceivedMessage message, Exception exception) - { - message.Content = Helper.AddExceptionProperty(message.Content, exception); - } + //private static void AddErrorReasonToContent(CapReceivedMessage message, Exception exception) + //{ + // message.Content = Helper.AddExceptionProperty(message.Content, exception); + //} - private async Task InvokeConsumerMethodAsync(CapReceivedMessage receivedMessage, CancellationToken cancellationToken) + private async Task InvokeConsumerMethodAsync(MediumMessage message, CancellationToken cancellationToken) { - if (!_selector.TryGetTopicExecutor(receivedMessage.Name, receivedMessage.Group, + if (!_selector.TryGetTopicExecutor( + message.Origin.GetName(), + message.Origin.GetGroup(), out var executor)) { - var error = $"Message can not be found subscriber. {receivedMessage} \r\n see: https://github.com/dotnetcore/CAP/issues/63"; + var error = $"Message can not be found subscriber. {message} \r\n see: https://github.com/dotnetcore/CAP/issues/63"; throw new SubscriberNotFoundException(error); } @@ -177,20 +172,25 @@ namespace DotNetCore.CAP var stopwatch = Stopwatch.StartNew(); var operationId = Guid.Empty; - var consumerContext = new ConsumerContext(executor, receivedMessage.ToMessageContext()); + var consumerContext = new ConsumerContext(executor, message.Origin); try { - operationId = s_diagnosticListener.WriteSubscriberInvokeBefore(consumerContext); + // operationId = s_diagnosticListener.WriteSubscriberInvokeBefore(consumerContext); var ret = await Invoker.InvokeAsync(consumerContext, cancellationToken); - s_diagnosticListener.WriteSubscriberInvokeAfter(operationId, consumerContext, startTime, - stopwatch.Elapsed); + // s_diagnosticListener.WriteSubscriberInvokeAfter(operationId, consumerContext, startTime,stopwatch.Elapsed); if (!string.IsNullOrEmpty(ret.CallbackName)) { - await _callbackMessageSender.SendAsync(ret.MessageId, ret.CallbackName, ret.Result); + var header = new Dictionary() + { + [Headers.CorrelationId] = message.Origin.GetId(), + [Headers.CorrelationSequence] = (message.Origin.GetCorrelationSequence() + 1).ToString() + }; + + await _sender.PublishAsync(ret.CallbackName, ret.Result, header, cancellationToken); } } catch (OperationCanceledException) @@ -199,7 +199,7 @@ namespace DotNetCore.CAP } catch (Exception ex) { - s_diagnosticListener.WriteSubscriberInvokeError(operationId, consumerContext, ex, startTime, stopwatch.Elapsed); + // s_diagnosticListener.WriteSubscriberInvokeError(operationId, consumerContext, ex, startTime, stopwatch.Elapsed); throw new SubscriberExecutionFailedException(ex.Message, ex); } diff --git a/src/DotNetCore.CAP/ISubscriberExecutor.cs b/src/DotNetCore.CAP/ISubscriberExecutor.cs index daeb60f..559bee0 100644 --- a/src/DotNetCore.CAP/ISubscriberExecutor.cs +++ b/src/DotNetCore.CAP/ISubscriberExecutor.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Threading.Tasks; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Persistence; namespace DotNetCore.CAP { @@ -12,6 +12,6 @@ namespace DotNetCore.CAP /// public interface ISubscriberExecutor { - Task ExecuteAsync(CapReceivedMessage message, CancellationToken cancellationToken = default); + Task ExecuteAsync(MediumMessage message, CancellationToken cancellationToken = default); } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Infrastructure/StatusName.cs b/src/DotNetCore.CAP/Infrastructure/StatusName.cs index f8c5142..018e28d 100644 --- a/src/DotNetCore.CAP/Infrastructure/StatusName.cs +++ b/src/DotNetCore.CAP/Infrastructure/StatusName.cs @@ -6,22 +6,10 @@ namespace DotNetCore.CAP.Infrastructure /// /// The message status name. /// - public struct StatusName + public enum StatusName { - public const string Scheduled = nameof(Scheduled); - public const string Succeeded = nameof(Succeeded); - public const string Failed = nameof(Failed); - - public static string Standardized(string input) - { - foreach (var item in typeof(StatusName).GetFields()) - { - if (item.Name.ToLower() == input.ToLower()) - { - return item.Name; - } - } - return string.Empty; - } + Failed = -1, + Scheduled, + Succeeded } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Internal/ConsumerContext.cs b/src/DotNetCore.CAP/Internal/ConsumerContext.cs index 49762ed..574c011 100644 --- a/src/DotNetCore.CAP/Internal/ConsumerContext.cs +++ b/src/DotNetCore.CAP/Internal/ConsumerContext.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Internal { @@ -15,7 +16,7 @@ namespace DotNetCore.CAP.Internal /// /// consumer method descriptor. /// received message. - public ConsumerContext(ConsumerExecutorDescriptor descriptor, MessageContext message) + public ConsumerContext(ConsumerExecutorDescriptor descriptor, Message message) { ConsumerDescriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor)); DeliverMessage = message ?? throw new ArgumentNullException(nameof(message)); @@ -29,6 +30,6 @@ namespace DotNetCore.CAP.Internal /// /// consumer received message. /// - public MessageContext DeliverMessage { get; } + public Message DeliverMessage { get; } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Internal/ConsumerInvokerFactory.cs b/src/DotNetCore.CAP/Internal/ConsumerInvokerFactory.cs index 90633dc..1feeb6a 100644 --- a/src/DotNetCore.CAP/Internal/ConsumerInvokerFactory.cs +++ b/src/DotNetCore.CAP/Internal/ConsumerInvokerFactory.cs @@ -10,25 +10,25 @@ namespace DotNetCore.CAP.Internal internal class ConsumerInvokerFactory : IConsumerInvokerFactory { private readonly ILoggerFactory _loggerFactory; - private readonly IMessagePacker _messagePacker; - private readonly IModelBinderFactory _modelBinderFactory; + //private readonly IMessagePacker _messagePacker; + //private readonly IModelBinderFactory _modelBinderFactory; private readonly IServiceProvider _serviceProvider; public ConsumerInvokerFactory( ILoggerFactory loggerFactory, - IMessagePacker messagePacker, - IModelBinderFactory modelBinderFactory, + //IMessagePacker messagePacker, + //IModelBinderFactory modelBinderFactory, IServiceProvider serviceProvider) { _loggerFactory = loggerFactory; - _messagePacker = messagePacker; - _modelBinderFactory = modelBinderFactory; + //_messagePacker = messagePacker; + //_modelBinderFactory = modelBinderFactory; _serviceProvider = serviceProvider; } public IConsumerInvoker CreateInvoker() { - return new DefaultConsumerInvoker(_loggerFactory, _serviceProvider, _messagePacker, _modelBinderFactory); + return new DefaultConsumerInvoker(_loggerFactory, _serviceProvider); } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Internal/ICallbackMessageSender.Default.cs b/src/DotNetCore.CAP/Internal/ICallbackMessageSender.Default.cs deleted file mode 100644 index 2114eed..0000000 --- a/src/DotNetCore.CAP/Internal/ICallbackMessageSender.Default.cs +++ /dev/null @@ -1,71 +0,0 @@ -// 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.Threading.Tasks; -using DotNetCore.CAP.Abstractions; -using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace DotNetCore.CAP.Internal -{ - internal class CallbackMessageSender : ICallbackMessageSender - { - private readonly IContentSerializer _contentSerializer; - private readonly ILogger _logger; - private readonly IMessagePacker _messagePacker; - private readonly IServiceProvider _serviceProvider; - - public CallbackMessageSender( - ILogger logger, - IServiceProvider serviceProvider, - IContentSerializer contentSerializer, - IMessagePacker messagePacker) - { - _logger = logger; - _serviceProvider = serviceProvider; - _contentSerializer = contentSerializer; - _messagePacker = messagePacker; - } - - public async Task SendAsync(string messageId, string topicName, object bodyObj) - { - string body; - if (bodyObj != null && Helper.IsComplexType(bodyObj.GetType())) - { - body = _contentSerializer.Serialize(bodyObj); - } - else - { - body = bodyObj?.ToString(); - } - - _logger.LogDebug($"Callback message will publishing, name:{topicName},content:{body}"); - - var callbackMessage = new CapMessageDto - { - Id = messageId, - Content = body - }; - - var content = _messagePacker.Pack(callbackMessage); - - var publishedMessage = new CapPublishedMessage - { - Id = SnowflakeId.Default().NextId(), - Name = topicName, - Content = content, - StatusName = StatusName.Scheduled - }; - - using (var scope = _serviceProvider.CreateScope()) - { - var provider = scope.ServiceProvider; - var callbackPublisher = provider.GetService(); - await callbackPublisher.PublishCallbackAsync(publishedMessage); - } - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs b/src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs index 4392cd0..62af0a7 100644 --- a/src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs +++ b/src/DotNetCore.CAP/Internal/IConsumerInvoker.Default.cs @@ -5,7 +5,7 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; -using DotNetCore.CAP.Abstractions; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Internal; using Microsoft.Extensions.Logging; @@ -15,18 +15,19 @@ namespace DotNetCore.CAP.Internal internal class DefaultConsumerInvoker : IConsumerInvoker { private readonly ILogger _logger; - private readonly IMessagePacker _messagePacker; - private readonly IModelBinderFactory _modelBinderFactory; + //private readonly IMessagePacker _messagePacker; + //private readonly IModelBinderFactory _modelBinderFactory; private readonly IServiceProvider _serviceProvider; public DefaultConsumerInvoker(ILoggerFactory loggerFactory, - IServiceProvider serviceProvider, - IMessagePacker messagePacker, - IModelBinderFactory modelBinderFactory) + IServiceProvider serviceProvider + //IMessagePacker messagePacker, + //IModelBinderFactory modelBinderFactory + ) { - _modelBinderFactory = modelBinderFactory; + //_modelBinderFactory = modelBinderFactory; _serviceProvider = serviceProvider; - _messagePacker = messagePacker; + //_messagePacker = messagePacker; _logger = loggerFactory.CreateLogger(); } @@ -58,20 +59,21 @@ namespace DotNetCore.CAP.Internal obj = ActivatorUtilities.GetServiceOrCreateInstance(provider, implType); } - var jsonContent = context.DeliverMessage.Content; - var message = _messagePacker.UnPack(jsonContent); + //var jsonContent = context.DeliverMessage.Content; + //var message = _messagePacker.UnPack(jsonContent); + var message = context.DeliverMessage; object resultObj; if (executor.MethodParameters.Length > 0) { - resultObj = await ExecuteWithParameterAsync(executor, obj, message.Content); + resultObj = await ExecuteWithParameterAsync(executor, obj, message.Value); } else { resultObj = await ExecuteAsync(executor, obj); } - return new ConsumerExecutedResult(resultObj, message.Id, message.CallbackName); + return new ConsumerExecutedResult(resultObj, message.GetId(), message.GetCallbackName()); } } @@ -85,31 +87,35 @@ namespace DotNetCore.CAP.Internal return executor.Execute(@class); } - private async Task ExecuteWithParameterAsync(ObjectMethodExecutor executor, - object @class, string parameterString) + private async Task ExecuteWithParameterAsync(ObjectMethodExecutor executor, object @class, object parameter) { var firstParameter = executor.MethodParameters[0]; try { - var binder = _modelBinderFactory.CreateBinder(firstParameter); - var bindResult = await binder.BindModelAsync(parameterString); - if (bindResult.IsSuccess) + if (executor.IsMethodAsync) { - if (executor.IsMethodAsync) - { - return await executor.ExecuteAsync(@class, bindResult.Model); - } - - return executor.Execute(@class, bindResult.Model); + return await executor.ExecuteAsync(@class, parameter); } - throw new MethodBindException( - $"Parameters:{firstParameter.Name} bind failed! ParameterString is: {parameterString} "); + return executor.Execute(@class, parameter); + //var binder = _modelBinderFactory.CreateBinder(firstParameter); + //var bindResult = await binder.BindModelAsync(parameter); + //if (bindResult.IsSuccess) + //{ + // if (executor.IsMethodAsync) + // { + // return await executor.ExecuteAsync(@class, bindResult.Model); + // } + + // return executor.Execute(@class, bindResult.Model); + //} + + //throw new MethodBindException( + // $"Parameters:{firstParameter.Name} bind failed! ParameterString is: {parameter} "); } catch (FormatException ex) { - _logger.ModelBinderFormattingException(executor.MethodInfo?.Name, firstParameter.Name, parameterString, - ex); + //_logger.ModelBinderFormattingException(executor.MethodInfo?.Name, firstParameter.Name, parameter, ex); return null; } } diff --git a/src/DotNetCore.CAP/Internal/IMessagePacker.Default.cs b/src/DotNetCore.CAP/Internal/IMessagePacker.Default.cs index 6de5ac8..ce06429 100644 --- a/src/DotNetCore.CAP/Internal/IMessagePacker.Default.cs +++ b/src/DotNetCore.CAP/Internal/IMessagePacker.Default.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using DotNetCore.CAP.Abstractions; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; namespace DotNetCore.CAP.Internal { diff --git a/src/DotNetCore.CAP/Internal/IMessageSender.Default.cs b/src/DotNetCore.CAP/Internal/IMessageSender.Default.cs new file mode 100644 index 0000000..364b4b5 --- /dev/null +++ b/src/DotNetCore.CAP/Internal/IMessageSender.Default.cs @@ -0,0 +1,184 @@ +// 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.Diagnostics; +using System.Threading.Tasks; +using DotNetCore.CAP.Diagnostics; +using DotNetCore.CAP.Infrastructure; +using DotNetCore.CAP.Messages; +using DotNetCore.CAP.Persistence; +using DotNetCore.CAP.Processor; +using DotNetCore.CAP.Serialization; +using DotNetCore.CAP.Transport; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace DotNetCore.CAP.Internal +{ + internal class MessageSender : IMessageSender + { + private readonly IDataStorage _dataStorage; + private readonly ISerializer _serializer; + private readonly ITransport _transport; + private readonly ILogger _logger; + private readonly IOptions _options; + + // ReSharper disable once InconsistentNaming + protected static readonly DiagnosticListener s_diagnosticListener = + new DiagnosticListener(CapDiagnosticListenerExtensions.DiagnosticListenerName); + + protected MessageSender( + ILogger logger, + IOptions options, + IDataStorage dataStorage, + ISerializer serializer, + ITransport transport) + { + _options = options; + _dataStorage = dataStorage; + _serializer = serializer; + _transport = transport; + _logger = logger; + } + + public async Task SendAsync(MediumMessage message) + { + bool retry; + OperateResult result; + do + { + var executedResult = await SendWithoutRetryAsync(message); + result = executedResult.Item2; + if (result == OperateResult.Success) + { + return result; + } + retry = executedResult.Item1; + } while (retry); + + return result; + } + + private async Task<(bool, OperateResult)> SendWithoutRetryAsync(MediumMessage message) + { + var startTime = DateTimeOffset.UtcNow; + var stopwatch = Stopwatch.StartNew(); + + var operationId = TracingBefore(message.Origin); + + var transportMsg = await _serializer.SerializeAsync(message.Origin); + var result = await _transport.SendAsync(transportMsg); + + stopwatch.Stop(); + if (result.Succeeded) + { + await SetSuccessfulState(message); + + if (operationId != null) + { + TracingAfter(operationId.Value, message.Origin, startTime, stopwatch.Elapsed); + } + + return (false, OperateResult.Success); + } + else + { + if (operationId != null) + { + TracingError(operationId.Value, message.Origin, result, startTime, stopwatch.Elapsed); + } + + var needRetry = await SetFailedState(message, result.Exception); + + return (needRetry, OperateResult.Failed(result.Exception)); + } + } + + private async Task SetSuccessfulState(MediumMessage message) + { + message.ExpiresAt = DateTime.Now.AddSeconds(_options.Value.SucceedMessageExpiredAfter); + await _dataStorage.ChangePublishStateAsync(message, StatusName.Succeeded); + } + + private async Task SetFailedState(MediumMessage message, Exception ex) + { + //TODO: Add exception to content + + var needRetry = UpdateMessageForRetry(message); + + await _dataStorage.ChangePublishStateAsync(message, StatusName.Failed); + + return needRetry; + } + + private bool UpdateMessageForRetry(MediumMessage message) + { + var retryBehavior = RetryBehavior.DefaultRetry; + + var retries = ++message.Retries; + message.ExpiresAt = message.Added.AddSeconds(retryBehavior.RetryIn(retries)); + + var retryCount = Math.Min(_options.Value.FailedRetryCount, retryBehavior.RetryCount); + if (retries >= retryCount) + { + if (retries == _options.Value.FailedRetryCount) + { + try + { + _options.Value.FailedThresholdCallback?.Invoke(MessageType.Publish, message.Origin); + + _logger.SenderAfterThreshold(message.DbId, _options.Value.FailedRetryCount); + } + catch (Exception ex) + { + _logger.ExecutedThresholdCallbackFailed(ex); + } + } + return false; + } + + _logger.SenderRetrying(message.DbId, retries); + + return true; + } + + private Guid? TracingBefore(Message message) + { + if (s_diagnosticListener.IsEnabled(CapDiagnosticListenerExtensions.CapBeforePublish)) + { + var operationId = Guid.NewGuid(); + + var eventData = new BrokerPublishEventData(operationId, "",_transport.Address, message,DateTimeOffset.UtcNow); + + s_diagnosticListener.Write(CapDiagnosticListenerExtensions.CapBeforePublish, eventData); + + return operationId; + } + + return null; + } + + private void TracingAfter(Guid operationId, Message message, DateTimeOffset startTime, TimeSpan du) + { + if (s_diagnosticListener.IsEnabled(CapDiagnosticListenerExtensions.CapAfterPublish)) + { + var eventData = new BrokerPublishEndEventData(operationId, "", _transport.Address, message, startTime, du); + + s_diagnosticListener.Write(CapDiagnosticListenerExtensions.CapAfterPublish, eventData); + } + } + + private void TracingError(Guid operationId, Message message, OperateResult result, DateTimeOffset startTime, TimeSpan du) + { + if (s_diagnosticListener.IsEnabled(CapDiagnosticListenerExtensions.CapAfterPublish)) + { + var ex = new PublisherSentFailedException(result.ToString(), result.Exception); + var eventData = new BrokerPublishErrorEventData(operationId, "", _transport.Address, + message, ex, startTime, du); + + s_diagnosticListener.Write(CapDiagnosticListenerExtensions.CapErrorPublish, eventData); + } + } + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Internal/ICallbackMessageSender.cs b/src/DotNetCore.CAP/Internal/IMessageSender.cs similarity index 64% rename from src/DotNetCore.CAP/Internal/ICallbackMessageSender.cs rename to src/DotNetCore.CAP/Internal/IMessageSender.cs index b66cf9b..de0143a 100644 --- a/src/DotNetCore.CAP/Internal/ICallbackMessageSender.cs +++ b/src/DotNetCore.CAP/Internal/IMessageSender.cs @@ -2,11 +2,12 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System.Threading.Tasks; +using DotNetCore.CAP.Persistence; namespace DotNetCore.CAP.Internal { - internal interface ICallbackMessageSender + public interface IMessageSender { - Task SendAsync(string messageId, string topicName, object bodyObj); + Task SendAsync(MediumMessage message); } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Internal/LoggerExtensions.cs b/src/DotNetCore.CAP/Internal/LoggerExtensions.cs index 5d7046f..f44cb17 100644 --- a/src/DotNetCore.CAP/Internal/LoggerExtensions.cs +++ b/src/DotNetCore.CAP/Internal/LoggerExtensions.cs @@ -10,12 +10,12 @@ namespace DotNetCore.CAP [SuppressMessage("ReSharper", "InconsistentNaming")] internal static class LoggerExtensions { - public static void ConsumerExecutedAfterThreshold(this ILogger logger, long messageId, int retries) + public static void ConsumerExecutedAfterThreshold(this ILogger logger, string messageId, int retries) { logger.LogWarning($"The Subscriber of the message({messageId}) still fails after {retries}th executions and we will stop retrying."); } - public static void SenderAfterThreshold(this ILogger logger, long messageId, int retries) + public static void SenderAfterThreshold(this ILogger logger, string messageId, int retries) { logger.LogWarning($"The Publisher of the message({messageId}) still fails after {retries}th sends and we will stop retrying."); } @@ -25,12 +25,12 @@ namespace DotNetCore.CAP logger.LogWarning(ex, "FailedThresholdCallback action raised an exception:" + ex.Message); } - public static void ConsumerExecutionRetrying(this ILogger logger, long messageId, int retries) + public static void ConsumerExecutionRetrying(this ILogger logger, string messageId, int retries) { logger.LogWarning($"The {retries}th retrying consume a message failed. message id: {messageId}"); } - public static void SenderRetrying(this ILogger logger, long messageId, int retries) + public static void SenderRetrying(this ILogger logger, string messageId, int retries) { logger.LogWarning($"The {retries}th retrying send a message failed. message id: {messageId} "); } diff --git a/src/DotNetCore.CAP/MessageContext.cs b/src/DotNetCore.CAP/MessageContext.cs deleted file mode 100644 index 17ae8ba..0000000 --- a/src/DotNetCore.CAP/MessageContext.cs +++ /dev/null @@ -1,33 +0,0 @@ -// 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.Collections.Generic; - -namespace DotNetCore.CAP -{ - /// - /// Message context - /// - public class MessageContext - { - /// - /// Gets or sets the message group. - /// - public string Group { get; set; } - - /// - /// Message name. - /// - public string Name { get; set; } - - /// - /// Message content - /// - public string Content { get; set; } - - public override string ToString() - { - return $"Group:{Group}, Name:{Name}, Content:{Content}"; - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Models/CapMessageDto.cs b/src/DotNetCore.CAP/Messages/CapMessageDto.cs similarity index 91% rename from src/DotNetCore.CAP/Models/CapMessageDto.cs rename to src/DotNetCore.CAP/Messages/CapMessageDto.cs index c79fb97..8f2fdf2 100644 --- a/src/DotNetCore.CAP/Models/CapMessageDto.cs +++ b/src/DotNetCore.CAP/Messages/CapMessageDto.cs @@ -4,7 +4,7 @@ using System; using DotNetCore.CAP.Infrastructure; -namespace DotNetCore.CAP.Models +namespace DotNetCore.CAP.Messages { public abstract class CapMessage { @@ -36,6 +36,5 @@ namespace DotNetCore.CAP.Models public override string Content { get; set; } - public override string CallbackName { get; set; } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Messages/Headers.cs b/src/DotNetCore.CAP/Messages/Headers.cs new file mode 100644 index 0000000..8aad623 --- /dev/null +++ b/src/DotNetCore.CAP/Messages/Headers.cs @@ -0,0 +1,30 @@ +namespace DotNetCore.CAP.Messages +{ + public static class Headers + { + /// + /// Id of the message. Either set the ID explicitly when sending a message, or Rebus will assign one to the message. + /// + public const string MessageId = "cap-msg-id"; + + public const string MessageName = "cap-msg-name"; + + public const string CorrelationId = "cap-corr-id"; + + public const string CorrelationSequence = "cap-corr-seq"; + + /// + /// Message value .NET type + /// + public const string Type = "cap-msg-type"; + + public const string CallbackName = "cap-callback-name"; + + public const string Group = "cap-msg-group"; + + public const string SentTime = "cap-senttime"; + + public const string ContentType = "cap-content-type"; + + } +} diff --git a/src/DotNetCore.CAP/Messages/Message.cs b/src/DotNetCore.CAP/Messages/Message.cs new file mode 100644 index 0000000..9fdd778 --- /dev/null +++ b/src/DotNetCore.CAP/Messages/Message.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; + +namespace DotNetCore.CAP.Messages +{ + public class Message + { + public Message(IDictionary headers, object value) + { + Headers = headers ?? throw new ArgumentNullException(nameof(headers)); + Value = value ?? throw new ArgumentNullException(nameof(value)); + } + + public IDictionary Headers { get; } + + public object Value { get; } + } + + public static class MessageExtensions + { + public static string GetId(this Message message) + { + message.Headers.TryGetValue(Headers.MessageId, out var value); + return value; + } + + public static string GetName(this Message message) + { + message.Headers.TryGetValue(Headers.MessageName, out var value); + return value; + } + + public static string GetCallbackName(this Message message) + { + message.Headers.TryGetValue(Headers.CallbackName, out var value); + return value; + } + + public static string GetGroup(this Message message) + { + message.Headers.TryGetValue(Headers.Group, out var value); + return value; + } + + public static int GetCorrelationSequence(this Message message) + { + if (message.Headers.TryGetValue(Headers.CorrelationSequence, out var value)) + { + return int.Parse(value); + } + + return 0; + } + } + +} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Models/MessageType.cs b/src/DotNetCore.CAP/Messages/MessageType.cs similarity index 87% rename from src/DotNetCore.CAP/Models/MessageType.cs rename to src/DotNetCore.CAP/Messages/MessageType.cs index 141040e..46ded20 100644 --- a/src/DotNetCore.CAP/Models/MessageType.cs +++ b/src/DotNetCore.CAP/Messages/MessageType.cs @@ -1,7 +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. -namespace DotNetCore.CAP.Models +namespace DotNetCore.CAP.Messages { public enum MessageType { diff --git a/src/DotNetCore.CAP/Messages/TransportMessage.cs b/src/DotNetCore.CAP/Messages/TransportMessage.cs new file mode 100644 index 0000000..b360ea9 --- /dev/null +++ b/src/DotNetCore.CAP/Messages/TransportMessage.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace DotNetCore.CAP.Messages +{ + /// + /// Message content field + /// + public class TransportMessage + { + public TransportMessage(Dictionary headers, byte[] body) + { + Headers = headers ?? throw new ArgumentNullException(nameof(headers)); + Body = body ?? throw new ArgumentNullException(nameof(body)); + } + + /// + /// Gets the headers of this message + /// + public Dictionary Headers { get; } + + /// + /// Gets the body object of this message + /// + public byte[] Body { get; } + + public string GetName() + { + return Headers.TryGetValue(Messages.Headers.MessageName, out var value) ? value : null; + } + } +} diff --git a/src/DotNetCore.CAP/Models/CapReceivedMessage.cs b/src/DotNetCore.CAP/Models/CapReceivedMessage.cs deleted file mode 100644 index 3e2dbf6..0000000 --- a/src/DotNetCore.CAP/Models/CapReceivedMessage.cs +++ /dev/null @@ -1,56 +0,0 @@ -// 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; - -namespace DotNetCore.CAP.Models -{ - public class CapReceivedMessage - { - /// - /// Initializes a new instance of . - /// - public CapReceivedMessage() - { - Added = DateTime.Now; - } - - public CapReceivedMessage(MessageContext message) : this() - { - Group = message.Group; - Name = message.Name; - Content = message.Content; - } - - public long Id { get; set; } - - public string Group { get; set; } - - public string Name { get; set; } - - public string Content { get; set; } - - public DateTime Added { get; set; } - - public DateTime? ExpiresAt { get; set; } - - public int Retries { get; set; } - - public string StatusName { get; set; } - - public MessageContext ToMessageContext() - { - return new MessageContext - { - Group = Group, - Name = Name, - Content = Content - }; - } - - public override string ToString() - { - return "name:" + Name + ", group:" + Group + ", content:" + Content; - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Persistence/CapPublishedMessage.cs b/src/DotNetCore.CAP/Persistence/CapPublishedMessage.cs new file mode 100644 index 0000000..8d68ed1 --- /dev/null +++ b/src/DotNetCore.CAP/Persistence/CapPublishedMessage.cs @@ -0,0 +1,25 @@ +// 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; + +namespace DotNetCore.CAP.Messages +{ + public class CapPublishedMessage + { + public CapPublishedMessage() + { + Added = DateTime.Now; + } + + public Message Message { get; set; } + + public DateTime Added { get; set; } + + public DateTime? ExpiresAt { get; set; } + + public int Retries { get; set; } + + public string StatusName { get; set; } + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Models/CapPublishedMessage.cs b/src/DotNetCore.CAP/Persistence/CapReceivedMessage.cs similarity index 68% rename from src/DotNetCore.CAP/Models/CapPublishedMessage.cs rename to src/DotNetCore.CAP/Persistence/CapReceivedMessage.cs index 955063d..1e29561 100644 --- a/src/DotNetCore.CAP/Models/CapPublishedMessage.cs +++ b/src/DotNetCore.CAP/Persistence/CapReceivedMessage.cs @@ -3,20 +3,22 @@ using System; -namespace DotNetCore.CAP.Models +namespace DotNetCore.CAP.Messages { - public class CapPublishedMessage + public class CapReceivedMessage { /// - /// Initializes a new instance of . + /// Initializes a new instance of . /// - public CapPublishedMessage() + public CapReceivedMessage() { Added = DateTime.Now; } public long Id { get; set; } + public string Group { get; set; } + public string Name { get; set; } public string Content { get; set; } @@ -31,7 +33,7 @@ namespace DotNetCore.CAP.Models public override string ToString() { - return "name:" + Name + ", content:" + Content; + return "name:" + Name + ", group:" + Group + ", content:" + Content; } } } \ No newline at end of file diff --git a/src/DotNetCore.CAP/Persistence/IDashboardQuerying.cs b/src/DotNetCore.CAP/Persistence/IDashboardQuerying.cs new file mode 100644 index 0000000..384a1f2 --- /dev/null +++ b/src/DotNetCore.CAP/Persistence/IDashboardQuerying.cs @@ -0,0 +1,26 @@ +//using System; +//using System.Collections.Generic; +//using DotNetCore.CAP.Dashboard.Monitoring; +//using DotNetCore.CAP.Messages; + +//namespace DotNetCore.CAP.Persistence +//{ +// public interface IDashboardQuerying +// { +// StatisticsDto GetStatistics(); + +// IList Messages(MessageQueryDto queryDto); + +// int PublishedFailedCount(); + +// int PublishedSucceededCount(); + +// int ReceivedFailedCount(); + +// int ReceivedSucceededCount(); + +// IDictionary HourlySucceededJobs(MessageType type); + +// IDictionary HourlyFailedJobs(MessageType type); +// } +//} diff --git a/src/DotNetCore.CAP/Persistence/IDataStorage.cs b/src/DotNetCore.CAP/Persistence/IDataStorage.cs new file mode 100644 index 0000000..ab18dca --- /dev/null +++ b/src/DotNetCore.CAP/Persistence/IDataStorage.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using DotNetCore.CAP.Infrastructure; +using DotNetCore.CAP.Messages; + +namespace DotNetCore.CAP.Persistence +{ + public interface IDataStorage + { + Task ChangePublishStateAsync(MediumMessage message, StatusName state); + + Task ChangeReceiveStateAsync(MediumMessage message, StatusName state); + + Task StoreMessageAsync(string name, Message content, object dbTransaction = null, CancellationToken cancellationToken = default); + + Task StoreMessageAsync(string name, string group, Message content, CancellationToken cancellationToken = default); + + Task DeleteExpiresAsync(string table, DateTime timeout, int batchCount = 1000, CancellationToken token = default); + + Task> GetPublishedMessagesOfNeedRetry(); + + Task> GetReceivedMessagesOfNeedRetry(); + + //Task GetPublishedMessageAsync(long id); + //Task GetReceivedMessageAsync(long id); + + //public void UpdateMessage(CapPublishedMessage message) + //{ + // if (message == null) + // { + // throw new ArgumentNullException(nameof(message)); + // } + + // var sql = + // $"UPDATE `{_prefix}.published` SET `Retries` = @Retries,`Content`= @Content,`ExpiresAt` = @ExpiresAt,`StatusName`=@StatusName WHERE `Id`=@Id;"; + // _dbConnection.Execute(sql, message); + //} + + //public void UpdateMessage(CapReceivedMessage message) + //{ + // if (message == null) + // { + // throw new ArgumentNullException(nameof(message)); + // } + + // var sql = $"UPDATE `{_prefix}.received` SET `Retries` = @Retries,`Content`= @Content,`ExpiresAt` = @ExpiresAt,`StatusName`=@StatusName WHERE `Id`=@Id;"; + // _dbConnection.Execute(sql, message); + //} + } +} diff --git a/src/DotNetCore.CAP/Persistence/IStorageInitializer.cs b/src/DotNetCore.CAP/Persistence/IStorageInitializer.cs new file mode 100644 index 0000000..141652d --- /dev/null +++ b/src/DotNetCore.CAP/Persistence/IStorageInitializer.cs @@ -0,0 +1,14 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace DotNetCore.CAP.Persistence +{ + public interface IStorageInitializer + { + Task InitializeAsync(CancellationToken cancellationToken); + + string GetPublishedTableName(); + + string GetReceivedTableName(); + } +} diff --git a/src/DotNetCore.CAP/Persistence/MediumMessage.cs b/src/DotNetCore.CAP/Persistence/MediumMessage.cs new file mode 100644 index 0000000..638f27d --- /dev/null +++ b/src/DotNetCore.CAP/Persistence/MediumMessage.cs @@ -0,0 +1,18 @@ +using System; +using DotNetCore.CAP.Messages; + +namespace DotNetCore.CAP.Persistence +{ + public class MediumMessage + { + public string DbId { get; set; } + + public Message Origin { get; set; } + + public DateTime Added { get; set; } + + public DateTime? ExpiresAt { get; set; } + + public int Retries { get; set; } + } +} diff --git a/src/DotNetCore.CAP/Processor/ICollectProcessor.cs b/src/DotNetCore.CAP/Processor/ICollectProcessor.cs deleted file mode 100644 index 9fd2625..0000000 --- a/src/DotNetCore.CAP/Processor/ICollectProcessor.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Core Community. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -namespace DotNetCore.CAP.Processor -{ - public interface ICollectProcessor : IProcessor - { - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Processor/IDispatcher.Default.cs b/src/DotNetCore.CAP/Processor/IDispatcher.Default.cs index b310bc9..60b7f17 100644 --- a/src/DotNetCore.CAP/Processor/IDispatcher.Default.cs +++ b/src/DotNetCore.CAP/Processor/IDispatcher.Default.cs @@ -5,7 +5,8 @@ using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Internal; +using DotNetCore.CAP.Persistence; using Microsoft.Extensions.Logging; namespace DotNetCore.CAP.Processor @@ -13,19 +14,18 @@ namespace DotNetCore.CAP.Processor public class Dispatcher : IDispatcher, IDisposable { private readonly CancellationTokenSource _cts = new CancellationTokenSource(); + private readonly IMessageSender _sender; private readonly ISubscriberExecutor _executor; private readonly ILogger _logger; - private readonly BlockingCollection _publishedMessageQueue = - new BlockingCollection(new ConcurrentQueue()); + private readonly BlockingCollection _publishedMessageQueue = + new BlockingCollection(new ConcurrentQueue()); - private readonly BlockingCollection _receivedMessageQueue = - new BlockingCollection(new ConcurrentQueue()); - - private readonly IPublishMessageSender _sender; + private readonly BlockingCollection _receivedMessageQueue = + new BlockingCollection(new ConcurrentQueue()); public Dispatcher(ILogger logger, - IPublishMessageSender sender, + IMessageSender sender, ISubscriberExecutor executor) { _logger = logger; @@ -36,12 +36,12 @@ namespace DotNetCore.CAP.Processor Task.Factory.StartNew(Processing, _cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); } - public void EnqueueToPublish(CapPublishedMessage message) + public void EnqueueToPublish(MediumMessage message) { _publishedMessageQueue.Add(message); } - public void EnqueueToExecute(CapReceivedMessage message) + public void EnqueueToExecute(MediumMessage message) { _receivedMessageQueue.Add(message); } @@ -67,7 +67,7 @@ namespace DotNetCore.CAP.Processor } catch (Exception ex) { - _logger.LogError(ex, $"An exception occurred when sending a message to the MQ. Topic:{message.Name}, Id:{message.Id}"); + _logger.LogError(ex, $"An exception occurred when sending a message to the MQ. Id:{message.DbId}"); } }); } diff --git a/src/DotNetCore.CAP/Processor/IProcessingServer.Cap.cs b/src/DotNetCore.CAP/Processor/IProcessingServer.Cap.cs index bb29d2b..e00128b 100644 --- a/src/DotNetCore.CAP/Processor/IProcessingServer.Cap.cs +++ b/src/DotNetCore.CAP/Processor/IProcessingServer.Cap.cs @@ -95,7 +95,7 @@ namespace DotNetCore.CAP.Processor { _provider.GetRequiredService(), _provider.GetRequiredService(), - _provider.GetRequiredService() + _provider.GetRequiredService() }; return returnedProcessors.ToArray(); diff --git a/src/DotNetCore.CAP/Processor/IProcessor.Collector.cs b/src/DotNetCore.CAP/Processor/IProcessor.Collector.cs new file mode 100644 index 0000000..c055109 --- /dev/null +++ b/src/DotNetCore.CAP/Processor/IProcessor.Collector.cs @@ -0,0 +1,60 @@ +// 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.Threading.Tasks; +using DotNetCore.CAP.Persistence; +using Microsoft.Extensions.Logging; + +namespace DotNetCore.CAP.Processor +{ + public class CollectorProcessor : IProcessor + { + private readonly ILogger _logger; + private readonly IStorageInitializer _initializer; + private readonly IDataStorage _storage; + + private const int ItemBatch = 1000; + private readonly TimeSpan _waitingInterval = TimeSpan.FromMinutes(5); + private readonly TimeSpan _delay = TimeSpan.FromSeconds(1); + + public CollectorProcessor( + ILogger logger, + IStorageInitializer initializer, + IDataStorage storage) + { + _logger = logger; + _initializer = initializer; + _storage = storage; + } + + public async Task ProcessAsync(ProcessingContext context) + { + var tables = new[] + { + _initializer.GetPublishedTableName(), + _initializer.GetReceivedTableName() + }; + + foreach (var table in tables) + { + _logger.LogDebug($"Collecting expired data from table [{table}]."); + + int deletedCount; + var time = DateTime.Now; + do + { + deletedCount = await _storage.DeleteExpiresAsync(table, time, ItemBatch, context.CancellationToken); + + if (deletedCount != 0) + { + await context.WaitAsync(_delay); + context.ThrowIfStopping(); + } + } while (deletedCount != 0); + } + + await context.WaitAsync(_waitingInterval); + } + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Processor/IProcessor.NeedRetry.cs b/src/DotNetCore.CAP/Processor/IProcessor.NeedRetry.cs index a7e92b3..b900e80 100644 --- a/src/DotNetCore.CAP/Processor/IProcessor.NeedRetry.cs +++ b/src/DotNetCore.CAP/Processor/IProcessor.NeedRetry.cs @@ -5,6 +5,8 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using DotNetCore.CAP.Internal; +using DotNetCore.CAP.Persistence; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -15,7 +17,7 @@ namespace DotNetCore.CAP.Processor { private readonly TimeSpan _delay = TimeSpan.FromSeconds(1); private readonly ILogger _logger; - private readonly IPublishMessageSender _publishMessageSender; + private readonly IMessageSender _messageSender; private readonly ISubscriberExecutor _subscriberExecutor; private readonly TimeSpan _waitingInterval; @@ -23,11 +25,11 @@ namespace DotNetCore.CAP.Processor IOptions options, ILogger logger, ISubscriberExecutor subscriberExecutor, - IPublishMessageSender publishMessageSender) + IMessageSender messageSender) { _logger = logger; _subscriberExecutor = subscriberExecutor; - _publishMessageSender = publishMessageSender; + _messageSender = messageSender; _waitingInterval = TimeSpan.FromSeconds(options.Value.FailedRetryInterval); } @@ -38,14 +40,14 @@ namespace DotNetCore.CAP.Processor throw new ArgumentNullException(nameof(context)); } - var connection = context.Provider.GetRequiredService(); + var storage = context.Provider.GetRequiredService(); - await Task.WhenAll(ProcessPublishedAsync(connection, context), ProcessReceivedAsync(connection, context)); + await Task.WhenAll(ProcessPublishedAsync(storage, context), ProcessReceivedAsync(storage, context)); await context.WaitAsync(_waitingInterval); } - private async Task ProcessPublishedAsync(IStorageConnection connection, ProcessingContext context) + private async Task ProcessPublishedAsync(IDataStorage connection, ProcessingContext context) { context.ThrowIfStopping(); @@ -53,13 +55,13 @@ namespace DotNetCore.CAP.Processor foreach (var message in messages) { - await _publishMessageSender.SendAsync(message); + await _messageSender.SendAsync(message); await context.WaitAsync(_delay); } } - private async Task ProcessReceivedAsync(IStorageConnection connection, ProcessingContext context) + private async Task ProcessReceivedAsync(IDataStorage connection, ProcessingContext context) { context.ThrowIfStopping(); diff --git a/src/DotNetCore.CAP/Processor/States/IState.Failed.cs b/src/DotNetCore.CAP/Processor/States/IState.Failed.cs deleted file mode 100644 index 4fb34b6..0000000 --- a/src/DotNetCore.CAP/Processor/States/IState.Failed.cs +++ /dev/null @@ -1,25 +0,0 @@ -// 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 DotNetCore.CAP.Models; - -namespace DotNetCore.CAP.Processor.States -{ - public class FailedState : IState - { - public const string StateName = "Failed"; - - public TimeSpan? ExpiresAfter => TimeSpan.FromDays(15); - - public string Name => StateName; - - public void Apply(CapPublishedMessage message, IStorageTransaction transaction) - { - } - - public void Apply(CapReceivedMessage message, IStorageTransaction transaction) - { - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Processor/States/IState.Scheduled.cs b/src/DotNetCore.CAP/Processor/States/IState.Scheduled.cs deleted file mode 100644 index b5cd805..0000000 --- a/src/DotNetCore.CAP/Processor/States/IState.Scheduled.cs +++ /dev/null @@ -1,25 +0,0 @@ -// 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 DotNetCore.CAP.Models; - -namespace DotNetCore.CAP.Processor.States -{ - public class ScheduledState : IState - { - public const string StateName = "Scheduled"; - - public TimeSpan? ExpiresAfter => null; - - public string Name => StateName; - - public void Apply(CapPublishedMessage message, IStorageTransaction transaction) - { - } - - public void Apply(CapReceivedMessage message, IStorageTransaction transaction) - { - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Processor/States/IState.Succeeded.cs b/src/DotNetCore.CAP/Processor/States/IState.Succeeded.cs deleted file mode 100644 index 3c0d16d..0000000 --- a/src/DotNetCore.CAP/Processor/States/IState.Succeeded.cs +++ /dev/null @@ -1,35 +0,0 @@ -// 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 DotNetCore.CAP.Models; - -namespace DotNetCore.CAP.Processor.States -{ - public class SucceededState : IState - { - public const string StateName = "Succeeded"; - - public SucceededState() - { - ExpiresAfter = TimeSpan.FromHours(1); - } - - public SucceededState(int expireAfterSeconds) - { - ExpiresAfter = TimeSpan.FromSeconds(expireAfterSeconds); - } - - public TimeSpan? ExpiresAfter { get; } - - public string Name => StateName; - - public void Apply(CapPublishedMessage message, IStorageTransaction transaction) - { - } - - public void Apply(CapReceivedMessage message, IStorageTransaction transaction) - { - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Processor/States/IState.cs b/src/DotNetCore.CAP/Processor/States/IState.cs deleted file mode 100644 index f1b8417..0000000 --- a/src/DotNetCore.CAP/Processor/States/IState.cs +++ /dev/null @@ -1,19 +0,0 @@ -// 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 DotNetCore.CAP.Models; - -namespace DotNetCore.CAP.Processor.States -{ - public interface IState - { - TimeSpan? ExpiresAfter { get; } - - string Name { get; } - - void Apply(CapPublishedMessage message, IStorageTransaction transaction); - - void Apply(CapReceivedMessage message, IStorageTransaction transaction); - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Processor/States/IStateChanger.Default.cs b/src/DotNetCore.CAP/Processor/States/IStateChanger.Default.cs deleted file mode 100644 index 436dcb6..0000000 --- a/src/DotNetCore.CAP/Processor/States/IStateChanger.Default.cs +++ /dev/null @@ -1,45 +0,0 @@ -// 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 DotNetCore.CAP.Models; - -namespace DotNetCore.CAP.Processor.States -{ - public class StateChanger : IStateChanger - { - public void ChangeState(CapPublishedMessage message, IState state, IStorageTransaction transaction) - { - var now = DateTime.Now; - if (state.ExpiresAfter != null) - { - message.ExpiresAt = now.Add(state.ExpiresAfter.Value); - } - else - { - message.ExpiresAt = null; - } - - message.StatusName = state.Name; - state.Apply(message, transaction); - transaction.UpdateMessage(message); - } - - public void ChangeState(CapReceivedMessage message, IState state, IStorageTransaction transaction) - { - var now = DateTime.Now; - if (state.ExpiresAfter != null) - { - message.ExpiresAt = now.Add(state.ExpiresAfter.Value); - } - else - { - message.ExpiresAt = null; - } - - message.StatusName = state.Name; - state.Apply(message, transaction); - transaction.UpdateMessage(message); - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Processor/States/IStateChanger.Extensions.cs b/src/DotNetCore.CAP/Processor/States/IStateChanger.Extensions.cs deleted file mode 100644 index b0e1e75..0000000 --- a/src/DotNetCore.CAP/Processor/States/IStateChanger.Extensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -// 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.Threading.Tasks; -using DotNetCore.CAP.Models; - -namespace DotNetCore.CAP.Processor.States -{ - public static class StateChangerExtensions - { - public static async Task ChangeStateAsync( - this IStateChanger @this, CapPublishedMessage message, IState state, IStorageConnection connection) - { - using (var transaction = connection.CreateTransaction()) - { - @this.ChangeState(message, state, transaction); - await transaction.CommitAsync(); - } - } - - public static async Task ChangeStateAsync( - this IStateChanger @this, CapReceivedMessage message, IState state, IStorageConnection connection) - { - using (var transaction = connection.CreateTransaction()) - { - @this.ChangeState(message, state, transaction); - await transaction.CommitAsync(); - } - } - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Processor/States/IStateChanger.cs b/src/DotNetCore.CAP/Processor/States/IStateChanger.cs deleted file mode 100644 index c15e23a..0000000 --- a/src/DotNetCore.CAP/Processor/States/IStateChanger.cs +++ /dev/null @@ -1,14 +0,0 @@ -// 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.Models; - -namespace DotNetCore.CAP.Processor.States -{ - public interface IStateChanger - { - void ChangeState(CapPublishedMessage message, IState state, IStorageTransaction transaction); - - void ChangeState(CapReceivedMessage message, IState state, IStorageTransaction transaction); - } -} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Serialization/ISerializer.cs b/src/DotNetCore.CAP/Serialization/ISerializer.cs new file mode 100644 index 0000000..75d05d5 --- /dev/null +++ b/src/DotNetCore.CAP/Serialization/ISerializer.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using DotNetCore.CAP.Messages; + +namespace DotNetCore.CAP.Serialization +{ + public interface ISerializer + { + /// + /// Serializes the given into a + /// + Task SerializeAsync(Message message); + + /// + /// Deserializes the given back into a + /// + Task DeserializeAsync(TransportMessage transportMessage); + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Serialization/StringSerializer.cs b/src/DotNetCore.CAP/Serialization/StringSerializer.cs new file mode 100644 index 0000000..42ba12a --- /dev/null +++ b/src/DotNetCore.CAP/Serialization/StringSerializer.cs @@ -0,0 +1,27 @@ +using System; +using System.Runtime.Serialization; +using DotNetCore.CAP.Messages; +using Newtonsoft.Json; + +namespace DotNetCore.CAP.Serialization +{ + public class StringSerializer + { + public static string Serialize(Message message) + { + return JsonConvert.SerializeObject(message); + } + + public static Message DeSerialize(string json) + { + try + { + return JsonConvert.DeserializeObject(json); + } + catch (Exception exception) + { + throw new SerializationException($"Could not deserialize JSON text '{json}'", exception); + } + } + } +} \ No newline at end of file diff --git a/src/DotNetCore.CAP/Transport/ITransport.cs b/src/DotNetCore.CAP/Transport/ITransport.cs new file mode 100644 index 0000000..7c9e2e0 --- /dev/null +++ b/src/DotNetCore.CAP/Transport/ITransport.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; +using DotNetCore.CAP.Messages; + +namespace DotNetCore.CAP.Transport +{ + public interface ITransport + { + string Address { get; } + + Task SendAsync(TransportMessage message); + } +} diff --git a/test/DotNetCore.CAP.MongoDB.Test/MongoDBMonitoringApiTest.cs b/test/DotNetCore.CAP.MongoDB.Test/MongoDBMonitoringApiTest.cs index 57e2fd6..58a6969 100644 --- a/test/DotNetCore.CAP.MongoDB.Test/MongoDBMonitoringApiTest.cs +++ b/test/DotNetCore.CAP.MongoDB.Test/MongoDBMonitoringApiTest.cs @@ -2,7 +2,7 @@ using System; using System.Linq; using DotNetCore.CAP.Dashboard.Monitoring; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using FluentAssertions; using Xunit; diff --git a/test/DotNetCore.CAP.MongoDB.Test/MongoDBStorageConnectionTest.cs b/test/DotNetCore.CAP.MongoDB.Test/MongoDBStorageConnectionTest.cs index 4034192..37537f9 100644 --- a/test/DotNetCore.CAP.MongoDB.Test/MongoDBStorageConnectionTest.cs +++ b/test/DotNetCore.CAP.MongoDB.Test/MongoDBStorageConnectionTest.cs @@ -1,6 +1,6 @@ using System; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; using MongoDB.Driver; diff --git a/test/DotNetCore.CAP.MySql.Test/MySqlStorageConnectionTest.cs b/test/DotNetCore.CAP.MySql.Test/MySqlStorageConnectionTest.cs index 042a6d8..82cfdcd 100644 --- a/test/DotNetCore.CAP.MySql.Test/MySqlStorageConnectionTest.cs +++ b/test/DotNetCore.CAP.MySql.Test/MySqlStorageConnectionTest.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Dapper; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; using Xunit; diff --git a/test/DotNetCore.CAP.PostgreSql.Test/PostgreSqlStorageConnectionTest.cs b/test/DotNetCore.CAP.PostgreSql.Test/PostgreSqlStorageConnectionTest.cs index a068161..323f16d 100644 --- a/test/DotNetCore.CAP.PostgreSql.Test/PostgreSqlStorageConnectionTest.cs +++ b/test/DotNetCore.CAP.PostgreSql.Test/PostgreSqlStorageConnectionTest.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Dapper; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.Options; using Xunit; diff --git a/test/DotNetCore.CAP.SqlServer.Test/SqlServerStorageConnectionTest.cs b/test/DotNetCore.CAP.SqlServer.Test/SqlServerStorageConnectionTest.cs index 0df9649..b019a18 100644 --- a/test/DotNetCore.CAP.SqlServer.Test/SqlServerStorageConnectionTest.cs +++ b/test/DotNetCore.CAP.SqlServer.Test/SqlServerStorageConnectionTest.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Dapper; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Xunit; namespace DotNetCore.CAP.SqlServer.Test diff --git a/test/DotNetCore.CAP.Test/CAP.BuilderTest.cs b/test/DotNetCore.CAP.Test/CAP.BuilderTest.cs index 402ef1a..f661ff2 100644 --- a/test/DotNetCore.CAP.Test/CAP.BuilderTest.cs +++ b/test/DotNetCore.CAP.Test/CAP.BuilderTest.cs @@ -1,8 +1,9 @@ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using DotNetCore.CAP.Abstractions; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Xunit; @@ -130,6 +131,12 @@ namespace DotNetCore.CAP.Test throw new NotImplementedException(); } + public Task PublishAsync(string name, T contentObj, IDictionary optionHeaders = null, + CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + public void Publish(string name, T contentObj, string callbackName = null) { throw new NotImplementedException(); diff --git a/test/DotNetCore.CAP.Test/CallbackMessageSenderTest.cs b/test/DotNetCore.CAP.Test/CallbackMessageSenderTest.cs index 6aa9a44..0509cd3 100644 --- a/test/DotNetCore.CAP.Test/CallbackMessageSenderTest.cs +++ b/test/DotNetCore.CAP.Test/CallbackMessageSenderTest.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using DotNetCore.CAP.Abstractions; using DotNetCore.CAP.Internal; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.DependencyInjection; using Moq; using Xunit; diff --git a/test/DotNetCore.CAP.Test/ConsumerInvokerTest.cs b/test/DotNetCore.CAP.Test/ConsumerInvokerTest.cs index fbee4ed..6da7c41 100644 --- a/test/DotNetCore.CAP.Test/ConsumerInvokerTest.cs +++ b/test/DotNetCore.CAP.Test/ConsumerInvokerTest.cs @@ -3,7 +3,7 @@ using System.Reflection; using System.Threading.Tasks; using DotNetCore.CAP.Abstractions; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; diff --git a/test/DotNetCore.CAP.Test/JsonContentSerializerTest.cs b/test/DotNetCore.CAP.Test/JsonContentSerializerTest.cs index 86bbfc3..fa7541e 100644 --- a/test/DotNetCore.CAP.Test/JsonContentSerializerTest.cs +++ b/test/DotNetCore.CAP.Test/JsonContentSerializerTest.cs @@ -1,6 +1,6 @@ using System; using DotNetCore.CAP.Internal; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using Newtonsoft.Json; using Xunit; diff --git a/test/DotNetCore.CAP.Test/Processor/StateChangerTest.cs b/test/DotNetCore.CAP.Test/Processor/StateChangerTest.cs index 26cb8ee..b6905e4 100644 --- a/test/DotNetCore.CAP.Test/Processor/StateChangerTest.cs +++ b/test/DotNetCore.CAP.Test/Processor/StateChangerTest.cs @@ -1,6 +1,6 @@ using System; using DotNetCore.CAP.Infrastructure; -using DotNetCore.CAP.Models; +using DotNetCore.CAP.Messages; using DotNetCore.CAP.Processor.States; using Moq; using Xunit; diff --git a/test/DotNetCore.CAP.Test/Sample.cs b/test/DotNetCore.CAP.Test/Sample.cs index fa4ea26..c4e1623 100644 --- a/test/DotNetCore.CAP.Test/Sample.cs +++ b/test/DotNetCore.CAP.Test/Sample.cs @@ -1,6 +1,5 @@ using System; using System.Threading.Tasks; -using DotNetCore.CAP.Models; using Newtonsoft.Json; using Xunit;