Spring Boot + Spring Session HttpSessionListener not working - spring-mvc

I have a spring boot (1.3.2) app in which I have implemented a HttpSessionListener. I registered the listener from a #Configration class
#Configuration
#EnableRedisHttpSession
public class ApplicationSessionConfiguration {
#Bean
public ServletListenerRegistrationBean<HttpSessionListener> sessionListener() {
return new ServletListenerRegistrationBean<HttpSessionListener>(new SessionListener());
}
}
I have debugged into ServletListenerRegistrationBean.onInitialize method and the listener is getting registered with the ServletContext. Problem is now when I make a dummy REST call to the app the session gets created properly and sent back as a SESSION cookie, but the HttpSessionListener.createSession method never gets called. I am not sure what I am missing here.

Looks like the feature you need is not yet released in a stable build. However as per this ticket this is fixed and is available in 1.1.0 M1 release for spring-session. You may want to try 1.1.0.RC1 release of spring-session to see if this helps what you want. Exact details on how to get this done can be found in this doc link
In case using 1.1.0.RC1 release is NOT an option (or if you prefer not use RC1 due to what ever reason), you can still intercept session creation and destroy events by extending default CookieHttpSessionStrategy with you own implementation (say MyCookieHttpSessionStrategy) and then overriding the onNewSession(..) and onInvalidateSession(..) to intercept these events. Register MyCookieHttpSessionStrategy as normal bean and you are all set (it'll be automatically picked up by Redis session repository). This works just fine with Redis sessions, I am using these events in my spring boot web app this way.
Hope this helps!!

Related

Pact provider verification is not calling provider-states

I have followed the examples on https://github.com/pact-foundation/pact-net#verifying-a-provider using version 4.0.0. My problem is that tests are failing because the provider state is not being set up. In the logs I see no mention of the /provider-states url being called and when I debug, the only call to ProviderStateMiddleware.InvokeAsync is for the actual API call. I can prove my test is passing by forcing the provider state setup in the constructor.
I found my issue. I was missing .Given(“some state”) in my consumer test.

How to configure Hangfire with Autofac in a dotnet core console app

I'm trying to port a working Hangfire setup embedded in a Kestrel webserver to a console app. I've modified the web app so it still provides the Hangfire dashboard but doesn't start its own Hangfire server.
The code I must port uses Autofac. I've added the Hangfire.Autofac package to the console app and have already performed all the steps detailed in the answer to Hangfire Autofac .net core 3.1
When I create a job (using the web app) the console app Hangfire server tries to execute the job but I get this failure message:
The requested service 'AED.ServicesLayer.JobProcessing.ProcessManager' has not been registered.
Investigating this we examine the setup of Autofac in the console app. This is how I set up my container.
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
var containerBuilder = new Autofac.ContainerBuilder();
containerBuilder.RegisterInstance(Log.Logger).AsImplementedInterfaces();
containerBuilder.RegisterModule(new RepositoryModule(config));
containerBuilder.RegisterType<UserService>().As<IUserService>();
containerBuilder.RegisterInstance(config).As<IConfiguration>();
containerBuilder.RegisterModule(new JobProcessingModule(config));
var container = containerBuilder.Build();
When the app is executed, hitting a breakpoint in JobProcessingModule proves the following line of code is executed.
builder.RegisterType<ProcessManager>().As<IProcessManager>();
It is very curious that the containerBuilder instance passed to JobProcessingModule.Load(containerBuilder) is not the same containerBuilder object on which RegisterModule is invoked.
However, experiments with simplified injectables suggest that this is normal, and the injected items are nevertheless visible in the registrations for the container that is returned.
Re-examining the logged failure we note that the class is mentioned by class name and not by interface. Changing the registration by removing the interface registration, like so
builder.RegisterType<ProcessManager>();//.As<IProcessManager>();
caused the ProcessManager to be found in the Hangfire console host but caused run-time errors in the web application when creating the job.
Registering it both ways caused ProcessManager to be found by both, with a new problem surfacing: cannot resolve dependencies. This, however, is merely a new case of the same problem.
While this allows me to move forward with getting a console host working, I do not like code I do not understand. Why should the console host require registration by class name when the web app does not?
Whatever is causing this has also caused Hangfire.IBackgroundJobClient to fail to resolve to the background job client. This is a hangfire class so it really does seem like there is a fundamental problem.
A lengthy investigation eventually revealed, confirmed by experiments, that this code
_recurringJobManager.AddOrUpdate(
insertResult.ToString(),
pm => pm.RunScheduledJobs(insertResult), interval.CrontabExpression
);
is responsible for the behaviour described in the question. AddOrUpdate is a generic method. When it is not explicitly typed it acquires its type from the class of the object passed to it. When the method is explicitly typed as the interface, like so
_recurringJobManager.AddOrUpdate<IProcessManager>(
insertResult.ToString(),
pm => pm.RunScheduledJobs(insertResult), interval.CrontabExpression
);
it remains compatible with the object, but the type acquired by Hangfire is the interface, and the console application can resolve ProcessManager from its interface.
Why the problem was not manifest in the web hosted Hangfire server remains a puzzle, but at least now I'm puzzled by the absence of a problem in a situation I don't have.

TelemetryProcessor not called without an InstrumentationKey?

I've created a class derived from ITelemetryProcessor, so I can capture telemetry data during a unit test of a C# .Net Class Library. Being a unit test, there is no InstrumentationKey provided as unit tests should have no network dependencies. (I cannot factor the telemetry to an injected interface.)
I create and use TelemetryClient's and log custom events during the unit test methods. However, I noticed my Process() method was not getting called when I logged telemetry items.
After doing some experimentation, I realized that if set an InstrumentationKey to a dummy Guid, then my Processor() method started to get called.
TelemetryConfiguration.Active.InstrumentationKey = Guid.NewGuid().ToString();
Question: why should I need to provide an InstrumentationKey in order for processors to be invoked?
Thanks
-John
TelemetryProcessor's are meant to apply additional processing/filtering to telemetry items before being sent to AI. If there is no ikey, then there is no point sending to AI as it will not be accepted anyway. Why run overhead of running all processors.

Xamarin.uitest how to close app instance

How to close and relaunch app in Xamarin.UI Test ? I want to restart app for each scenario in feature .
Platform: android
There is no quit() or close() session methods like we have in appium.
Calling ConfigureApp.Android.StartApp() in your test will launch a new session of your application for you to interact with (just make sure to save the new object).
However, with the use of NUnit, methods tagged with [Setup] will run automatically before every method tagged with[Test]. That means most test suites only use the ConfigureApp.Android.StartApp() method once, in [Setup].
Given you are on your are using Xamarin UI Test project,
You can use Finish() to close the application,
or
MoveTaskToBack(true) to minimize the application.
So that you can call them from your Test.cs, you'll need to write myBackdoorClose and myBackdoorMinimize functions (since Finish() and MoveTaskToBack(true) are only available in the App.cs context). How to do that, read here!
You can actually use Xamarin.UITest.ConfigureApp.Android.StartApp(AppDataMode.DoNotClear) in your test. It will close the app and restart it without clearing the app's data, all while the test keeps running.
This is a cross-platform solution; you can use Xamarin.UITest.ConfigureApp.iOS.StartApp... too.

Are group subscriptions automatically handled on Reconnect?

I have a chat room using SignalR Hub for its messaging. Occasionally I get reports from users where it 'freezes'. Now this can be interpreted as no messages are coming through, I suspect as they have been dropped from a group.
My question is, does the connection get re-subscribed back into its groups automatically, or do you have to do something yourself in the Reconnect method:
public Task Reconnect(IEnumerable<string> groups)
{
return Clients.rejoined(Context.ConnectionId, DateTime.Now.ToString());
}
Yes, in 1.0.0.0-alpha1 you can enable auto rejoining of groups by using the new AutoRejoiningGroupsModule pipeline module using the EnableAutoRejoiningGroups extension method for the hub pipeline you build. This feature was not available in previous versions of the framework.
So you would end up with this somewhere in your startup code:
GlobalHost.HubPipeline.EnableAutoRejoiningGroups();
UPDATE:
Please note that the final version of SignalR 1.0 made auto-rejoining of groups the default behavior and so EnableAutoRejoiningGroups was removed. You can see this answer for more details.

Resources