How to clear database entries on browser close in jsf? - spring

In our application which makes
use of JSF/PrimeFaces, Spring and Hibernate once a user logs in, we set a flag in the DB until the user logs out from the application or the session expires. The problem is, we need to clear this flag in the DB even when he simply closes the browser without proper logout. To acheieve this, I have already tried jquery $window.unload and $window.bind functions which actually invokes some JS function which is associated with <p:remoteCommand> which in turn invokes a managed bean method to clear the DB. However, I later came to know this is not reliable and while testing also we saw the event was not firing consistently. How can I achieve the DB cleanup anyway?

Listening on browser close is not reliable. You can use beforeunload event for that, but this is not supported on every webbrowser the world is aware of and even disableable/spoofable/hackable by the enduser. Then we're not talking about the race condition during firing the ajax request: would the ajax request arrive in its entirety right before the browser is closed? More than often this is not the case and the browser close wins over the ajax request.
Just listen server side on session expiration instead.
#WebListener
public class MyHttpSessionListener implements HttpSessionListener {
#Override
public void sessionCreated(HttpSessionEvent event) {
// NOOP.
}
#Override
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession session = event.getSession();
// Do your job here.
// ...
}
}
Note that this is also invoked when you explicitly invoke ExternalContext#invalidateSession() (or HttpSession#invalidate()) during programmatic logout.

Related

Axon Event Handler Read All Events Each Restart

I put Event Handler to query my events in axon framework in my spring application. I can put an event from my command up and I can read them from my query app.until reboot time no problem But when I reboot my query app Each time it reads same events again at the beginning and it cause duplicate process. How can I commit an event when I read it?
ToMyAxonConfig
#Bean
public TokenStore tokenStore(Serializer serializer, EntityManagerProvider entityManagerProvider) {
return JpaTokenStore.builder()
.entityManagerProvider(entityManagerProvider)
.serializer(serializer)
.build();
}
#Autowired
public void configureProcessors(EventProcessingConfigurer eventProcessingConfigurer) {
TrackingEventProcessorConfiguration tepConfig = TrackingEventProcessorConfiguration.forSingleThreadedProcessing().andInitialTrackingToken(StreamableMessageSource::createHeadToken);
eventProcessingConfigurer.registerTrackingEventProcessorConfiguration(config -> tepConfig);
}
I have the feeling you haven't configured a TokenStore.
In that case, Axon Framework will give you an InMemoryTokenStore implementation meaning that on every restart, you will get all Events again from your Event Store because your app does not have a 'state' for the token.
You can check the ref-guide to know more about it and also how to configure one properly from several options.
How can I commit an event when I read it?
Also to correct a bit the word usage here, Events are 'commited' on your Event Store. If you are talking about your Query Side App, you do not commit Events there but you just save a state based on Events.

What event is fired when Laravel app is being shutdown?

Specifically what I am doing is in my AppServiceProvider->boot() method I am creating a singleton class like below:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
$this->app->singleton('App\Support\PushNotificationHelper', function ($app) {
return new PushNotificationHelper();
});
}
}
The helper class is needed for a Queue worker job I use for Pushing Notifications to mobile apps. When the mobile device is an Apple device I need to establish a curl connection and have the connection persist beyond the life of the queue worker job. This is why I am using the singleton to hold the connection like:
class PushNotificationHelper {
protected $http2Connection;
protected $http2Expire ;
public function getConnection($options) {
$this->http2Connection = curl_init();
curl_setopt_array($this->http2Connection, $options);
return $this->http2Connection;
}
Apple claims if I connect and disconnect repeatedly then they will issue a Denial of Service (DOS). My app literally sends 1000s of notifications per hour. When ever I use the connection I check for errors and will close/reopen the connection when needed like:
curl_close($http2Connection);
However I would like to know how I can detect when the app will close for good so I can gracefully close the connection. If there is no way to do this will it harm my server over time by leaving open connections hanging, lets say months of running if the app was to start/stop several times a day ?
Another option could be is there a curl option to tell the connection to auto disconnect after so much time. (I force a close and reopen every 4 hours) so if I could tell connection to auto-close after 5 hours at least then maybe it would be self-cleaning?
IMHO you can try to add a terminating callback to your app instance, for example in the AppServiceProvider, i.e.:
public function boot()
{
$this->app->terminating(function () {
// your terminating code here
});
}
You can use the boot method for anything.
From laravel docs:
This method is called after all other service providers have been
registered, meaning you have access to all other services that have
been registered by the framework
The key is that boot method run when all services are registered, so, you can inject services in the boot method definition.
public function boot(SomeService $someService, OtherService $otherService)
{
$someService->doSomething();
$otherService->doSomething();
}
In my opinion, you must to use this method to run code required by your app in all contexts: user logged in, user logged out, post, get, put, etc., etc.

Kentico Tapping into Page Level Events

We are creating webevents in a DB other than Kentico. These webevents are then used for enterprise reporting. I need to implement the same inside Kentico project.
Is there an event that can fire after the page has loaded so that i can create my web event with page name and user information if logged in.
I have also seen in the past that with events, the Request and Session objects are not available. However, HTTPContext.Current is available. I need the Request and Session objects.
We are using Kentico version 7.0.92 and have a portal template site.
Now, i don't want to use portal template page to create events since this code executes multiple times with each request for a page.
Basically, i am interested in the PageName, Session and Request objects.
I have looked around Kentico 7 documentation. Looks like we have CMSRequestEvents but haven't been able to find sample code.
Update:
Looks like the missing piece is CMSContext class. Now just trying to find the right event for CMSRequestEvents, where i have the Session object available.
I'd suggest modifying Kentico\CMS\Global.asax.cs in the following way:
public override void Init()
{
base.Init();
CMSRequestEvents.AcquireRequestState.After += AcquireRequestState_After;
}
void AcquireRequestState_After(object sender, EventArgs e)
{
// Do your stuff...
}
By that time the HttpContext.Current.Session should already be initialized. Page name can be retrieved from the HttpContext.Current.Request which should never be null.

What's the best way to detect the start of a session (similar to Global.ashx's Session_Start) when using ServiceStack SessionFeature?

I've enabled Sessions support in service stack like:
container.Register<IRedisClientsManager>(c => container.Resolve<PooledRedisClientManager>());
container.Register<ICacheClient>(c => c.Resolve<IRedisClientsManager>().GetCacheClient());
container.Register<ISessionFactory>(c => new SessionFactory(c.Resolve<ICacheClient>()));
//RE: https://github.com/ServiceStack/ServiceStack/wiki/Sessions
Plugins.Add(new SessionFeature());
I see that ss-id and ss-pidd cookies are set upon visiting the site, however I would like to know when a session is started (i.e., first request from that user) so i can capture the incoming referrer url.
Using traditional asp.net sessions, i'd use Session_Start in Global, however this doesn't fire for me while using SS sessions.
Is there a good way to detect this session start event when using ServiceStack? I didn't find any reference in my queries online, or on the ServiceStack Sessions wiki.
There is currently no "Session Started" event in ServiceStack's Sessions feature, but there are some events on IAuthSession that might be useful to use instead, e.g:
public interface IAuthSession
{
...
void OnRegistered(IServiceBase registrationService);
void OnLogout(IServiceBase authService);
void OnAuthenticated(IServiceBase authService, IAuthSession session,
IOAuthTokens tokens, Dictionary<string, string> authInfo);
}
If you still would like to see an OnSessionStarted event request it as a feature in ServiceStack's GitHub issues (and include your use-case), so we can keep track of it.

How to handle a session timeout exception (with MVP Places and Activities)?

how do you handle a time out request in a GWT app ?
Here is a snipped of my web.xml file :
<session-config>
<session-timeout>30</session-timeout>
</session-config>
My GWT project is based on MVP Activities and Places.
Whenever the user waits more than 30mn, i want to display a popup and redirect the user to the login page. Here is what i do for
all RPC services :
public void onFailure(Throwable caught) {
...
if (caught instanceof InvocationException) {
{
Window.alert("Time out de session. Veuillez vous reconnecter. 2");
Window.open(GWT.getHostPageBaseURL() + "identification.html", "_self", null);
return;
}
...}
It works but several things are annoying :
1) the caught exception should be RequestTimeoutException. But it's not caught, which is why i use InvocationException instead.
How come it's not caught ?
2) how can i handle this exception in a more generic way ? It's a bit stupid to have to catch that exception in all RPC services ...
I read about some AsyncCallbackAdapter class ...
3) Right now i handle RPC services only but of course time out exception occurs everywhere : links, buttons, page refresh ...
I'm using MVP Places and Activities.
Is there a way to catch that exception when the user tries to go to a place ?
Thanks for helping
RequestTimeoutException is thrown when server is not responding.
You should create you own checked exception, something like SessionTimeoutException and handle it in you client code. GWT knows how to handle (serialize) checked exceptions and pass them to your client code: http://code.google.com/webtoolkit/doc/latest/tutorial/RPC.html#exceptions
To handle this in application-wide way, you can hook into RPC mechanism, by creating you own generator for remote services: How to redirect to login page after session expire in GWT RPC call
The easiest way (without changing all existing code) would be to set a Timer to periodically check (every few minutes) the server session. When session times out show a modal DialogBox (preventing user input on other widgets) notifying user he/she needs to login again.

Resources