invalidate the session in Tapestry from JUnit tests - session

I am working on a large complicated Tapestry service. It generally works but sometimes when running for a while the session it is in will get invalidated, and it will send an error. There is nothing about this service that should need the session but sometimes it depends on a service that depends on a service that "needs" the session.
I want to pragmatically invalidate the session in my tests, so I can protect against regression. Ideally I would do this without killing the session in the production code, which is how I am testing it now.
Specificly, we are testing the service by running the server and making http calls, and also by extending TapestryIoCTestCase. I can't think of any clean way to invalidate a session from the http client tests. and the Mock session created for TapestryIoCTestCase does not support invalidation.
I have looked into setting the session time-out in the tests, but I was hoping for something more direct.
Thanks
e for instance someone at somepoint wanted to set the locale in one of our dependencies
java.lang.IllegalStateException: setAttribute: Session [31943F300613D2105C9AF8602397557D] has already been invalidated
at org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1437)
at org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1402)
at org.apache.catalina.session.StandardSessionFacade.setAttribute(StandardSessionFacade.java:156)
at org.apache.tapestry5.internal.services.SessionImpl.setAttribute(SessionImpl.java:67)
at org.apache.tapestry5.internal.services.SessionApplicationStatePersistenceStrategy.set(SessionApplicationStatePersistenceStrategy.java:68)
at $ApplicationStatePersistenceStrategy_13c1cafe292.set($ApplicationStatePersistenceStrategy_13c1cafe292.java)
at org.apache.tapestry5.internal.services.ApplicationStateManagerImpl$ApplicationStateAdapter.set(ApplicationStateManagerImpl.java:50)
at org.apache.tapestry5.internal.services.ApplicationStateManagerImpl.set(ApplicationStateManagerImpl.java:138)
at $ApplicationStateManager_13c1cafe272.set($ApplicationStateManager_13c1cafe272.java)

I'm assuming you are referring to the HttpSession which can be invalidated by calling HttpSession.invalidate(). Though in all honesty your question provides too little information for a proper answer. What is your setup? What have you tried? What does your code look like? Are you mocking your Servlet Container? Etc...
Questions without code are hard to answer.

Related

Hibernate Open Session in View: Transaction per Request?

I'm using Hibernate with Spring on Tomcat. I've been reading and re-reading the oft pointed to JBoss wiki page on the topic, and that has been helpful. But it leaves me with some questions.
The idea of starting a transaction for every request troubles me. I guess I could limit the filter to certain controllers -- maybe put all my controllers that need a transaction under a pseudo "tx" path or something. But isn't it a bad idea to use transactions if you don't know if you're going to need one? And if I'm just doing reads in some request -- reads that very likely may come from a cache -- aren't I better off without a transaction?
I've read posts mentioning how they handled the transactions at the service layer, and I'd like to do this with Spring. But then what does the filter code look like? I still want the session available in my view for some lazy loading.
If all I have to do is call sessionFactory.getCurrentSession() in my filter, how does it get "freed" back to the session factory for re-use? (I expected to see a session.close() or something, even when using transactions.) Who is telling the session factory that that session can be reused?
Perhaps it's the beginTransaction() call that binds a given database connection to a given session for the duration of a request? Otherwise, a session pulls db connections from the pool as needed, right?
Thanks for your patience with all my questions.
(And if your answer is going to be a link to the Spring documentation, you'll just make me cry. You don't want that, do you? I'll pay real money if people would stop answering Spring-related questions that way.)
Your concerns are valid, the solution provided on the wiki page is too simplistic. The transaction should not be managed at the web layer - it should be handled at the service layer.
The correct implementation would open a session and bind it to a thread in the filter. No transaction is started. The session is put in flush mode never - read only mode. A service call would set the session to flush mode auto & start / commit the transaction. Once the service method finishes the session flush mode is reverted back to never.
There is also an option to not open the session in the filter. Each service layer call would open a separate session & transaction - after the service call is done the session is not closed, but registered for deferred close. The session will be closed after the web request processing is complete.
Spring provides OpensessionInViewFilter which works as described above. So ignore the jboss wiki article and just configure the OpensessionInViewFilter - everything will be fine.
SessionFactory.getCurrentSession() - internally creates and assigns the session to a thread local. Each request / thread will have its own session. Once the web request processing is complete the session will be closed. From within your code you just need to use SessionFactory.getCurrentSession() and don't have to close it. The code sample on the jboss wiki page is wrong - it should have a SessionFactory.getCurrentSession().close() in the finally block. Or they might be using JTA transaction and configured hibernate to open/close session in conjunction with the JTA transaction.
It is not a problem if the filter creates a session for every request, because the sessions are coming from a session pool, and they will be reused. From the view of the OS, nothing happens.
A hibernate session is, by the fact, a tcp (or socket/pipe) connection to the database server. The cost of the db conn creation is very dependent from the sql type (postgresql is notably bad in this, altough it is very good in every anything). But it doesn't means really anything, because hibernate reuses the database connections.
The simple hibernate filter solution starts a new transaction on the session for every requests, too. It is transaction from the view of the SQL: it is a "BEGIN" and "COMMIT" query. It is always costly, and this should be reduced.
IMHO a possible solution were, if the transactions were started only at the first query of the current request. Maybe spring has something usable for this.

Is Terracotta used professionally?

Today at work I had a discussion with my co-workers and my boss about stateless / stateful beans (we just finished a project using JSF, it was the first time anyone at this company did something JSF related) and my boss said that he doesn't really like Session scoped beans (or even conversation / KeepAlive scoped ones). One of his arguments was that if we have for example 4 Tomcats and there is a request from the user then we aren't really sure that it will be "captured" by the same Tomcat every single time and the problem is that if during the first time a request comes and a session bean is created it's created only on that one Tomcat and the others don't know about it.
One of the solutions he mentioned was a so called "sticky session" which enforces requests from a given user to be handled by the same Tomcat every time. A second solution according to him would be storing all the data in the "view", but that would mean storing the whole state in the POST, somehow I don't really like that idea. Then he mentioned storing the state in the DB and querying it if a request that requires it arrives. I thought that it would be a really huge performance hit, but he said that it really wouldn't be a concern since the DBs should be prepared for such tasks.
The last solution which I'm interested in was the Terracotta Server which, from what he told us, is supposed to store the session bean for all Tomcats (which are synchronized with it and then if a requests comes in they look for session beans inside Terracotta). Seems kinda cool and scalable, but he said that he didn't really see it ever used in large professional systems, is that right? I tried some info on it but failed, is there something wrong with Terracotta that stops people from using it?
It is used by professionals, just look a their customers page.
http://www.terracotta.org/company/customers?src=/index.html

ColdFusion Session issue - multiple users behind one proxy IP -- cftoken and cfid seems to be shared

I have an application that uses coldfusion's session management (instead of the J2EE) session management.
We have one client, who has recently switched their company's traffic to us to come viaa proxy server in their network.
So, to our Coldfusion server, it appears that all traffic is coming from this one IP Address, for all of the accounts of this one company..
Of the session variables, Part 1 is kept in a cflock, and Part 2 is kept in editable session variables. I may be misundestanding, but we have done it this way as we modify some values as needed throughout the application's usage.
We are now running into an issue of this client having their session variables mixed up (?). We have one case where we set a timestamp.. and when it comes time to look it up, it's empty. From the looks of it this is happening because of another user on the same token.
My initial thoughts are to look into modifying our existing session management to somehow generate a unique cftoken/cfid, or to start using jsession_ID, if this solves the problem at all.
I have done some basic research on this issue and couldn't find anything similar, so I thought I'd ask here.
Thanks!
I've run into similar problems on and off for years.
JSession cookies seem to help (no hard data on that) but one solution that I've implemented repoeatedly is using no-cache and cache expiry headers on every page.
http://www.bpurcell.org/blog/index.cfm?entry=1075&mode=entry gives some specifics on how to implement this.
In extreme cases, we've been forced to pass the token and cfid in the links/forms, but that is a PITA to implement, so I'd try the cache expiry/prevention soluiton first.
As far as I know, there are no "cons" in using J2EE session variables, unless you really need session to be active after user closes the browser. I think you should try and see how application behaves with it and see if that saves you trouble of refactoring.
To be sure that you are using all other settings try this:
<cfdump var="#APPLICATION.GetApplicationSettings()#" label="Application settings" />
If you have sessionmanagement and client cookies turned on, everything is fine, so try j2ee session variables.

ColdFusion sessions not being timed out

We have 2 core applications running on our servers on CF 8, and both have the exact same session timeout set in the application CFC (2 hours at the moment). However we're seeing that sessions are spiralling out of control for one of the applications (currently at 120,000+ on one server), lets call it AppA whereas AppB seems fine (and AppB is the one we'd expect a lot more traffic to).
So I did some further digging and found out that most of the sessions for AppA have been idle for many hours with the highest value I've seen so far being over 11 hours.
We're not actually doing that much with sessions so I'm a little confused as to why they're not being timed out as expected. Also I've dumped the this scope in the application CFC and it is showing the expected value for sessionTimeout.
The only thing I had noticed is that in one instance we're assigning a variable on the Request scope from a Session variable. If it were a different scope I would maybe think that is causing some sort of reference that GC (or whatever) can't clear.
In terms of the spiral, I'd say that's to do with some requests which aren't passing through the CFID/CFTOKEN to maintain the session. This could be web service calls, CFHTTP requests, search engine bots, etc. Sounds like one of your apps is experiencing this. If this is the case then for CFHTTP pass the CFID/CFTOKEN through to maintain sessions. Web services bit more tricky, you'll need to create a 'key' which is passed back and forth, whole separate topic! Bots can be handled by having some conditionals to set the session timeout value.
For the 11 hours, I'd say thats due to it been kept alive by something. Some continual polling? Reocurring AJAX request? It would have to be something that continues to pass the ID/TOKEN through.
I used to get server lockups in CF6.1 when I was persisting CFCs in the application or session scopes. Now I instantiate them in the request scope and the lockups stopped happening (with no noticeable performance drop). Maybe you have a similar issue.
Actually turns out the sessions were started from another App which wasn't over-riding the default value in the base Application.cfc (including the application name).

How do deal with OpenX XMLRPC authentication / sessions

I am having trouble with Openx; here is the issue
OpenX::Services::Base.connection returns the class variable ##connection which is populated by OpenX::Services::Base.connection if it has previously not been initialized.
The problem with it being a class variable is that it persists across connections, which means if there is a lull in activity, the XMLRPC session between my site and OpenX will time out, and the OpenX API has no provisions for communicating an expired session, which would be wasteful anyways as it would require a request before every communication just to verify that the session was still valid.
What I think would be a better way to do it would be to instantiate a connection at the beginning of any request that needs OpenX support, and to close it at the end, ensuring that there is no possibility of a session time-out on the XMLRPC side of things.
Has anyone else encounted this when using OpenX / OpenX XMLRPC? If so how did you resolve this issue?
I have a try/catch block around the OpenX RPC call, and I wrote an exception translator. If I detect a session timeout I will execute a again the login operation, I will take the new session id and I will run the failed OpenX call again. It is a little bit more complicated than having a cron job in order to keep the session alive but more performant and robust (in my opinion).
We faced the same issue. Our solution: Create a unauthenticated controller which does some simple interactions with the OpenX API (just to keep it live) and have this URL invoked by a cron job every 5-10 min.
What solution did you use?

Resources