ASP.NET Core 3.1 - Health Check UI is not working - asp.net-core-3.1

i have developed an ASP.NET Core 3.1 MVC Application with customized Health Check. It's perfectly working fine as shown below.
However, the UI is always empty as the /health-api always returns empty array.
It's in ASP.NET 3.1 Core application which can be located at https://github.com/prawin2k/HealhCheckMVC/tree/master/HealhCheckMVC
.NET Core version - 3.1 (MVC)
Healthchecks version - Latest
Operative system: Windows Server 2016
Others: Visual Studio 2019

In my case the health checks UI itself not launching and crashing the .net core 3.1 web API application.
Error Message:
Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: HealthChecks.UI.Core.Notifications.IHealthCheckFailureNotifier Lifetime: Scoped ImplementationType: HealthChecks.UI.Core.Notifications.WebHookFailureNotifier': Unable to resolve service for type 'HealthChecks.UI.Core.Data.HealthChecksDb' while attempting to activate 'HealthChecks.UI.Core.Notifications.WebHookFailureNotifier'.)
Fix: Add any UI storage provider . In my case I have choosen AddInMemoryStorage()
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddHealthChecks()
.AddDbContextCheck<PollDbContext>() //nuget: Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
.AddApplicationInsightsPublisher(); //nuget: AspNetCore.HealthChecks.Publisher.ApplicationInsights
services.AddHealthChecksUI() //nuget: AspNetCore.HealthChecks.UI
.AddInMemoryStorage(); //nuget: AspNetCore.HealthChecks.UI.InMemory.Storage
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseHealthChecks("/healthcheck", new HealthCheckOptions
{
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse //nuget: AspNetCore.HealthChecks.UI.Client
});
//nuget: AspNetCore.HealthChecks.UI
app.UseHealthChecksUI(options =>
{
options.UIPath = "/healthchecks-ui";
options.ApiPath = "/health-ui-api";
});
...
}
appsettings.json
"HealthChecks-UI": {
"DisableMigrations": true,
"HealthChecks": [
{
"Name": "PollManager",
"Uri": "/healthcheck"
}
],
"Webhooks": [
{
"Name": "",
"Uri": "",
"Payload": "",
"RestoredPayload": ""
}
],
"EvaluationTimeOnSeconds": 10,
"MinimumSecondsBetweenFailureNotifications": 60,
"MaximumExecutionHistoriesPerEndpoint": 15
}

Related

EF Core InMemory DB does not apply configurations from assembly and returns no data

I'm trying to test my app with an InMemory DB so I can run Postman tests against it.
I have a docker-compose that successfully starts it:
version: '3.9'
services:
api:
image: ${DOCKER_REGISTRY-}api-test
build:
context: ../
dockerfile: API/Dockerfile
ports:
- 80:80
- 443:443
environment:
- ASPNETCORE_ENVIRONMENT=Test
The test env is setup for the InMemory DB:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"UseOnlyInMemoryDatabase": true
}
I successfully configure the DB service in here:
namespace Infrastructure
{
public static class Dependencies
{
public static void ConfigureServices(IConfiguration configuration, IServiceCollection services)
{
var useOnlyInMemoryDatabase = false;
if (configuration["UseOnlyInMemoryDatabase"] != null)
{
useOnlyInMemoryDatabase = bool.Parse(configuration["UseOnlyInMemoryDatabase"]);
}
if (useOnlyInMemoryDatabase)
{
services.AddDbContext<BookDesinerContext>(c =>
c.UseInMemoryDatabase("BookDesignerDB"));
}
else
{
...
}
}
}
}
I get the successful log like this:
info: API[0]
PublicApi App created...
info: API[0]
Seeding Database...
Starting Seed Category
Ended Seeding and applying
warn: Microsoft.EntityFrameworkCore.Model.Validation[10620]
The property 'GameCell.Settings' is a collection or enumeration type with a value converter but with no value comparer. Set a value comparer to ensure the collection/enumeration elements are compared correctly.
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 6.0.8 initialized 'BookDesinerContext' using provider 'Microsoft.EntityFrameworkCore.InMemory:6.0.7' with options: StoreName=BookDesignerDB
info: API[0]
LAUNCHING API
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://[::]:80
Notice the log from "Ended Seeding and Applying", which is set in OnModelCreating()
// Seed
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
Console.WriteLine("Ended Seeding and applying");
All my configs seed data like this:
namespace Infrastructure.Data.Seeding
{
public class TagConfig : IEntityTypeConfiguration<Tag>
{
public void Configure(EntityTypeBuilder<Tag> builder)
{
builder.ToTable("Tag");
builder.Property(t => t.Value).IsRequired();
builder.HasData(
new Tag
{
TagId = 1,
Key = "Held",
Value = "Borja"
},
new Tag
{
TagId = 2,
Key = "Genre",
Value = "Pirat"
}
);
}
}
}
But when I access the collection under http://localhost/api/Tags I get []. I can use a REST client to create new resources and read them, but I want my seed data to be applied. Why does the config not apply the values from builder.HasData()?
For the seeding to actually happen, you need a call to:
context.Database.EnsureCreated();
Try:
services.GetRequiredService<BookDesinerContext>().Database.EnsureCreated();

Spring Cloud Function and SQSEvent Triggered AWS Lambda Function

I'm unable to get a Spring-Cloud based AWS Lambda Function with an SQS Message trigger to work. I'm using the Spring Cloud Function AWS adapter version 2.0.1.RELEASE and attempting to deploy to the AWS EU-WEST-2 Region.
My SpringBootRequestHandler is defined as follows:
import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
public class ReplicationHandler extends SpringBootRequestHandler<SQSEvent, String>{
}
My #Bean function looks as follows:
#Bean
public Function<SQSEvent, String> handleEvent() {
return value -> processEvent((SQSEvent)value);
}
I feed this with the following test event:
{
"Records": [
{
"messageId": "02a4e04b-a1d2-417a-b073-56123be35ac6",
"receiptHandle": "AQEB0fsSc76vU9Y6vQEz",
"body": "hello world",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "1553860061037",
"SenderId": "AIDAIVEA3AGEU7NF6DRAG",
"ApproximateFirstReceiveTimestamp": "1553860061042"
},
"messageAttributes": {},
"md5OfBody": "a4d19d8b1019e01bb875eea6232bf2f1",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:eu-west-2:XXXXX:YYYYY",
"awsRegion": "eu-west-2"
}
]
}
When I run this , I get the following error:
{
"errorMessage": "reactor.core.publisher.FluxJust cannot be cast to com.amazonaws.services.lambda.runtime.events.SQSEvent",
"errorType": "java.lang.ClassCastException",
"stackTrace": [
"org.springframework.cloud.function.adapter.aws.SpringFunctionInitializer.apply(SpringFunctionInitializer.java:132)",
"org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler.handleRequest(SpringBootRequestHandler.java:48)"
]
}
Anyone have any suggestions around what's going wrong here? Alternatively, if there are any working samples on the web for my exact scenario, that would be good as well.

Drools stateful session per request

We are trying to use Drool as our rule engine service. What we done till now is listed below
Deployed workbench 7.2.Final
Deployed KIE server 7.2.0.Final
Configured some data objects, rules, deployed the changes to KIE server and we are able to execute the rule using rest API
Most of our requirements satisfied by stateless session (Give a set of data, execute the rule and return the data, that's it) . But using stateless we have to compromise many of the important features provided by Drools stateful session.
So we are trying to use stateful session per request. Which means the session should get disposed as soon as the request end. Also, parallel request should not interfere each other even if the session name is same
We found about container runtime strategy configuration (Workbench > Deploy > {any container} > Process Configuration > Runtime strategy)
But even after configure the container strategy to Per Request, it still behave same as Singleton (the session is not getting disposed after each request)
Few place we read it as, run time strategy only implemented in jBPM
The way we make request to KIE server is shown below
Request: POST {HOST}/kie-server/services/rest/server/containers/instances/TestRequest_1.0.4
{
"lookup": "ab-session", //stateful session
"commands": [
{
"insert": {
"out-identifier": "125",
"object": {
"com.myteam.testrequest.Product": {
"id": "123",
"name": "Hoo Hoo",
"count": 0
}
},
"return-object": "true"
}
},
{
"insert": {
"out-identifier": "126",
"object": {
"com.myteam.testrequest.Product": {
"id": "123",
"name": "Hoo Hoo",
"count": 0
}
},
"return-object": "true"
}
},
{"fire-all-rules": "hf2"}
]
}
We need help in achieving this requirement. Also, please help understand if we done something wrong
In kmodule.xml you may try to add "prototype" scope, because default is "singleton":
<ksession name="SessionName" type="stateful" default="false" clockType="realtime" scope="prototype"/>

How to add a ETW provider to an existing service fabric cluster using powershell?

I have already created a service fabric cluster with azure diagnostics and it is functional currently with my services deployed into that cluster. I have an ETW EventSource in my service that I would like to start collecting events from because my service code already uses this event source to write my service related events. Since the cluster is already enabled for azure diagnostics and my services are already deployed into that cluster, I think it is a simple matter of updating the ETW provider with my event source in this service fabric cluster. Here is the exported template (only a partial is shown that is relevant for azure diagnostics):
{
"properties": {
"publisher": "Microsoft.Azure.Diagnostics",
"type": "IaaSDiagnostics",
"typeHandlerVersion": "1.5",
"autoUpgradeMinorVersion": true,
"settings": {
"WadCfg": {
"DiagnosticMonitorConfiguration": {
"overallQuotaInMB": "50000",
"EtwProviders": {
"EtwEventSourceProviderConfiguration": [
{
"provider": "Microsoft-ServiceFabric-Actors",
"scheduledTransferKeywordFilter": "1",
"scheduledTransferPeriod": "PT5M",
"DefaultEvents": {
"eventDestination": "ServiceFabricReliableActorEventTable"
}
},
{
"provider": "Microsoft-ServiceFabric-Services",
"scheduledTransferPeriod": "PT5M",
"DefaultEvents": {
"eventDestination": "ServiceFabricReliableServiceEventTable"
}
},
{
"provider": "Bb.ServiceFabric.Infrastructure.Container",
"scheduledTransferPeriod": "PT1M",
"DefaultEvents": {
"eventDestination": "ServiceFabricReliableServiceEventTable"
}
}
],
"EtwManifestProviderConfiguration": [
{
"provider": "cbd93bc2-71e5-4566-b3a7-595d8eeca6e8",
"scheduledTransferLogLevelFilter": "Information",
"scheduledTransferKeywordFilter": "4611686018427387904",
"scheduledTransferPeriod": "PT5M",
"DefaultEvents": {
"eventDestination": "ServiceFabricSystemEventTable"
}
}
]
}
}
},
"StorageAccount": "sfdgsmsraghuplaygrou6827"
}
},
"name": "VMDiagnosticsVmExt_vmNodeType0Name"
}
I would like to update following EtwProviders/EtwEventSourceProviderConfiguration to contain following section (as MyCompany.MyServices.MyStatelessService is the name of my service's EventSource):
{
"provider": "MyCompany.MyServices.MyStatelessService",
"scheduledTransferPeriod": "PT5M",
"DefaultEvents": {
"eventDestination": "ServiceFabricReliableServiceEventTable"
}
}
Here are my questions:
Is this the correct way of inserting an ETW provider/EventSource (from my service) into an existing cluster (that is already enabled with azure diagnostics)?
Can I add this event source (as a ETW event source provider) using a powershell command(s)?
If so, what is the exact powershell command (using all the information from the above code fragment)?
Note: I am using .net framework 4.5.2.
All seems good with the added configuration above. Just be aware that for ETWProviders the EventDestination cannot contain hyphens (-), yours don't so you are ok.
To update the Windows Azure Diagnostics (WAD) agent configuration, you can use either PowerShell or Cloud Explorer in Visual Studio.
For the former, simply update the ARM template and use the New-AzureRmResourceGroupDeployment cmdlet. See here for further information: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-diagnostics-how-to-setup-wad/#update-diagnostics-to-collect-and-upload-logs-from-new-eventsource-channels
For using Cloud Explorer in Visual Studio. Browse to your Virtual Machine Scale Set (as this is the Azure resource that holds the WAD configuration). Right-click and choose Update Diagnostics. In the dialog shown, you have the option to upload a private and public configuration file. Simple take a .json document containing the {"WadCfg": {}} element, and upload that as a public configuration.
If you need to update the private configuration specifies the storage account name and AccessKey:
{
"storageAccountName": "",
"storageAccountKey": "",
"storageAccountEndPoint": "https://core.windows.net",
}
Hope this helps.
Mikkel

Spring Cloud + Ribbon + Eureka (service registry) and Relative URLs (rels)

If I do a call to the autowired RestTemplate it works like a charm:
GET on http://localhost:18990/microservice2/ (service registry):
{
"_links": {
"hl:echo": { "href": "http://localhost:18989/microservice2/echo?echoMessage={echoMessage}", "templated": true },
"curies":
[ {
"href": "/microservice2/generated-docs/api-guide.html#resources-{rel}",
"name": "hl",
"templated": true
}
]
}
}
From micro service 1(calling micro service 2 using the RestTemplate):
#Autowired
private RestTemplate restTemplate;
URI targetUrl = UriComponentsBuilder.fromUriString("http://microservice2")
.path("/microservice2/echo")
.queryParam("echoMessage", "echoMessage")
.build()
.toUri();
EchoMessageResource response = restTemplate.getForObject(targetUrl, EchoMessageResource.class);
OK
Ribbon does use Eureka to get to the real server behind the scenes.
If I add a rel then it does NOT work. I get a 404.
FROM:
URI targetUrl = UriComponentsBuilder.fromUriString("http://microservice2")
.path("/microservice2/echo")
.queryParam("echoMessage", "echoMessage")
.build()
.toUri();
TO:
URI targetUrl = UriComponentsBuilder.fromUriString("http://microservice2")
.path("/microservice2/hl:echo")
.queryParam("echoMessage", "echoMessage")
.build()
.toUri();
EchoMessageResource response = restTemplate.getForObject(targetUrl, EchoMessageResource.class);
KO
404
What is the way to use a rel ? In my example hl:echo.
OK. As The Spring Hateoas Client side support documentation does not make any reference to Ribbon, I make the assumption that Spring Hateoas does not support Ribbon at all.