From d5ad04137fa12ec5ccc4a29868e1b1f419c40ad5 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Wed, 9 Jul 2025 17:52:42 +0100 Subject: [PATCH 1/2] more updates for correlation id --- TestHosts/TestHosts/Common/Class.cs | 63 +++++++++++++++++++ .../Controllers/DeveloperController.cs | 2 +- TestHosts/TestHosts/Startup.cs | 31 ++++----- TestHosts/TestHosts/TestHosts.csproj | 2 +- TestHosts/TestHosts/appsettings.json | 6 ++ TestHosts/TestHosts/nlog.development.config | 2 +- 6 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 TestHosts/TestHosts/Common/Class.cs diff --git a/TestHosts/TestHosts/Common/Class.cs b/TestHosts/TestHosts/Common/Class.cs new file mode 100644 index 0000000..c9493f9 --- /dev/null +++ b/TestHosts/TestHosts/Common/Class.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.ObjectModel; +using CoreWCF; +using CoreWCF.Channels; +using CoreWCF.Description; +using CoreWCF.Dispatcher; +using System.Linq; + +namespace TestHosts.Common +{ + public class CorrelationIdMessageInspector : IDispatchMessageInspector + { + public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) + { + if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out Object httpRequestMessageObject) + && httpRequestMessageObject is HttpRequestMessageProperty httpRequest) + { + String correlationId = httpRequest.Headers["correlationId"]; + + if (!string.IsNullOrWhiteSpace(correlationId)) + { + using (NLog.ScopeContext.PushProperty("CorrelationId", correlationId)) { + // Store it globally per operation (e.g., ThreadStatic, AsyncLocal, or Logging Context) + NLog.ScopeContext.PushProperty("CorrelationId", correlationId); + } + } + } + + return null; + } + + public void BeforeSendReply(ref Message reply, object correlationState) + { + + } + } + + public class CorrelationIdBehavior : IServiceBehavior + { + public void Validate(ServiceDescription serviceDescription, + ServiceHostBase serviceHostBase) { + + } + + public void AddBindingParameters(ServiceDescription serviceDescription, + ServiceHostBase serviceHostBase, + Collection endpoints, + BindingParameterCollection bindingParameters) { + + } + + public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers.OfType()) + { + foreach (EndpointDispatcher endpoint in dispatcher.Endpoints) + { + endpoint.DispatchRuntime.MessageInspectors.Add(new CorrelationIdMessageInspector()); + } + } + } + } +} diff --git a/TestHosts/TestHosts/Controllers/DeveloperController.cs b/TestHosts/TestHosts/Controllers/DeveloperController.cs index 7919b99..16b4496 100644 --- a/TestHosts/TestHosts/Controllers/DeveloperController.cs +++ b/TestHosts/TestHosts/Controllers/DeveloperController.cs @@ -47,7 +47,7 @@ await resolvedContext.Context.PrePayUsers.AddAsync(new PrePayUser UserId = userId, UserName = request.UserName, }, cancellationToken); - await resolvedContext.Context.SaveChangesAsync(cancellationToken); + //await resolvedContext.Context.SaveChangesAsync(cancellationToken); } return this.Ok(); diff --git a/TestHosts/TestHosts/Startup.cs b/TestHosts/TestHosts/Startup.cs index cda188b..df29561 100644 --- a/TestHosts/TestHosts/Startup.cs +++ b/TestHosts/TestHosts/Startup.cs @@ -4,20 +4,10 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using NLog.Extensions.Logging; +using TestHosts.Common; namespace TestHosts { - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Diagnostics.Metrics; - using System.DirectoryServices.Protocols; - using System.IO; - using System.Linq; - using System.Runtime.InteropServices; - using System.ServiceModel; - using System.Threading; - using System.Threading.Tasks; using CoreWCF; using CoreWCF.Configuration; using CoreWCF.Description; @@ -37,6 +27,18 @@ namespace TestHosts using Shared.General; using Shared.Logger; using Shared.Middleware; + using Shared.TennantContext; + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Metrics; + using System.DirectoryServices.Protocols; + using System.IO; + using System.Linq; + using System.Runtime.InteropServices; + using System.ServiceModel; + using System.Threading; + using System.Threading.Tasks; using TestHosts.SoapServices; using ILogger = Microsoft.Extensions.Logging.ILogger; @@ -99,12 +101,13 @@ public void ConfigureServices(IServiceCollection services) String pataPawaConnectionString = ConfigurationReader.GetConnectionString("PataPawaReadModel"); services.AddDbContext(builder => builder.UseSqlServer(pataPawaConnectionString)); } - + services.AddScoped(x => new TenantContext()); services.AddSingleton(); services.AddMvc(); services.AddServiceModelServices().AddServiceModelMetadata(); services.AddSingleton(); + services.AddSingleton(); bool logRequests = ConfigurationReader.GetValueOrDefault("MiddlewareLogging", "LogRequests", true); @@ -137,7 +140,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF ILogger logger = loggerFactory.CreateLogger("TestHosts"); Logger.Initialise(logger); - app.UseMiddleware(); + app.UseMiddleware(); app.AddRequestLogging(); app.AddResponseLogging(); app.AddExceptionHandler(); @@ -174,7 +177,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF app.UseServiceModel(builder => { builder.AddService((serviceOptions) => { serviceOptions.DebugBehavior.IncludeExceptionDetailInFaults = true; - }) + }) // Add a BasicHttpBinding at a specific endpoint .AddServiceEndpoint(new BasicHttpBinding(), "/PataPawaPostPayService/basichttp"); }); diff --git a/TestHosts/TestHosts/TestHosts.csproj b/TestHosts/TestHosts/TestHosts.csproj index 14c3cc2..a51e610 100644 --- a/TestHosts/TestHosts/TestHosts.csproj +++ b/TestHosts/TestHosts/TestHosts.csproj @@ -21,7 +21,7 @@ - + diff --git a/TestHosts/TestHosts/appsettings.json b/TestHosts/TestHosts/appsettings.json index b31fb9b..de1d473 100644 --- a/TestHosts/TestHosts/appsettings.json +++ b/TestHosts/TestHosts/appsettings.json @@ -1,4 +1,10 @@ { + "Logging": { + "LogLevel": { + "Microsoft": "None", // Disable all Microsoft logs + "System": "None" // Disable all System logs + } + }, "ConnectionStrings": { "TestBankReadModel": "server=localhost;user id=sa;password=Sc0tland;database=TestBankReadModel;Encrypt=false", "PataPawaReadModel": "server=localhost;user id=sa;password=Sc0tland;database=PataPawaReadModel;Encrypt=false" diff --git a/TestHosts/TestHosts/nlog.development.config b/TestHosts/TestHosts/nlog.development.config index ca33ed0..1233c5e 100644 --- a/TestHosts/TestHosts/nlog.development.config +++ b/TestHosts/TestHosts/nlog.development.config @@ -5,7 +5,7 @@ Date: Wed, 9 Jul 2025 17:59:58 +0100 Subject: [PATCH 2/2] code review fixes --- TestHosts/TestHosts/Common/Class.cs | 63 ------------------- .../TestHosts/Common/CorrelationIdBehavior.cs | 34 ++++++++++ .../Common/CorrelationIdMessageInspector.cs | 33 ++++++++++ .../Controllers/DeveloperController.cs | 2 +- 4 files changed, 68 insertions(+), 64 deletions(-) delete mode 100644 TestHosts/TestHosts/Common/Class.cs create mode 100644 TestHosts/TestHosts/Common/CorrelationIdBehavior.cs create mode 100644 TestHosts/TestHosts/Common/CorrelationIdMessageInspector.cs diff --git a/TestHosts/TestHosts/Common/Class.cs b/TestHosts/TestHosts/Common/Class.cs deleted file mode 100644 index c9493f9..0000000 --- a/TestHosts/TestHosts/Common/Class.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.ObjectModel; -using CoreWCF; -using CoreWCF.Channels; -using CoreWCF.Description; -using CoreWCF.Dispatcher; -using System.Linq; - -namespace TestHosts.Common -{ - public class CorrelationIdMessageInspector : IDispatchMessageInspector - { - public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) - { - if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out Object httpRequestMessageObject) - && httpRequestMessageObject is HttpRequestMessageProperty httpRequest) - { - String correlationId = httpRequest.Headers["correlationId"]; - - if (!string.IsNullOrWhiteSpace(correlationId)) - { - using (NLog.ScopeContext.PushProperty("CorrelationId", correlationId)) { - // Store it globally per operation (e.g., ThreadStatic, AsyncLocal, or Logging Context) - NLog.ScopeContext.PushProperty("CorrelationId", correlationId); - } - } - } - - return null; - } - - public void BeforeSendReply(ref Message reply, object correlationState) - { - - } - } - - public class CorrelationIdBehavior : IServiceBehavior - { - public void Validate(ServiceDescription serviceDescription, - ServiceHostBase serviceHostBase) { - - } - - public void AddBindingParameters(ServiceDescription serviceDescription, - ServiceHostBase serviceHostBase, - Collection endpoints, - BindingParameterCollection bindingParameters) { - - } - - public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) - { - foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers.OfType()) - { - foreach (EndpointDispatcher endpoint in dispatcher.Endpoints) - { - endpoint.DispatchRuntime.MessageInspectors.Add(new CorrelationIdMessageInspector()); - } - } - } - } -} diff --git a/TestHosts/TestHosts/Common/CorrelationIdBehavior.cs b/TestHosts/TestHosts/Common/CorrelationIdBehavior.cs new file mode 100644 index 0000000..6ee5d0f --- /dev/null +++ b/TestHosts/TestHosts/Common/CorrelationIdBehavior.cs @@ -0,0 +1,34 @@ +using System.Collections.ObjectModel; +using System.Linq; +using CoreWCF; +using CoreWCF.Channels; +using CoreWCF.Description; +using CoreWCF.Dispatcher; + +namespace TestHosts.Common; + +public class CorrelationIdBehavior : IServiceBehavior +{ + public void Validate(ServiceDescription serviceDescription, + ServiceHostBase serviceHostBase) { + // No validation needed for correlation ID behavior + } + + public void AddBindingParameters(ServiceDescription serviceDescription, + ServiceHostBase serviceHostBase, + Collection endpoints, + BindingParameterCollection bindingParameters) { + // No binding parameters needed for correlation ID behavior + } + + public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers.OfType()) + { + foreach (EndpointDispatcher endpoint in dispatcher.Endpoints) + { + endpoint.DispatchRuntime.MessageInspectors.Add(new CorrelationIdMessageInspector()); + } + } + } +} \ No newline at end of file diff --git a/TestHosts/TestHosts/Common/CorrelationIdMessageInspector.cs b/TestHosts/TestHosts/Common/CorrelationIdMessageInspector.cs new file mode 100644 index 0000000..03d7522 --- /dev/null +++ b/TestHosts/TestHosts/Common/CorrelationIdMessageInspector.cs @@ -0,0 +1,33 @@ +using System; +using CoreWCF; +using CoreWCF.Channels; +using CoreWCF.Dispatcher; + +namespace TestHosts.Common; + +public class CorrelationIdMessageInspector : IDispatchMessageInspector +{ + public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) + { + if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out Object httpRequestMessageObject) + && httpRequestMessageObject is HttpRequestMessageProperty httpRequest) + { + String correlationId = httpRequest.Headers["correlationId"]; + + if (!string.IsNullOrWhiteSpace(correlationId)) + { + using (NLog.ScopeContext.PushProperty("CorrelationId", correlationId)) { + // Store it globally per operation (e.g., ThreadStatic, AsyncLocal, or Logging Context) + NLog.ScopeContext.PushProperty("CorrelationId", correlationId); + } + } + } + + return null; + } + + public void BeforeSendReply(ref Message reply, object correlationState) + { + // Optionally, you can add the correlation ID to the reply message headers + } +} \ No newline at end of file diff --git a/TestHosts/TestHosts/Controllers/DeveloperController.cs b/TestHosts/TestHosts/Controllers/DeveloperController.cs index 16b4496..7919b99 100644 --- a/TestHosts/TestHosts/Controllers/DeveloperController.cs +++ b/TestHosts/TestHosts/Controllers/DeveloperController.cs @@ -47,7 +47,7 @@ await resolvedContext.Context.PrePayUsers.AddAsync(new PrePayUser UserId = userId, UserName = request.UserName, }, cancellationToken); - //await resolvedContext.Context.SaveChangesAsync(cancellationToken); + await resolvedContext.Context.SaveChangesAsync(cancellationToken); } return this.Ok();