1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.eclipse.jetty.server.session;
16
17 import java.io.ByteArrayInputStream;
18 import java.io.ByteArrayOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.ObjectInputStream;
22 import java.io.ObjectOutputStream;
23 import java.sql.Connection;
24 import java.sql.PreparedStatement;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.ListIterator;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.concurrent.ConcurrentHashMap;
33 import java.util.concurrent.atomic.AtomicReference;
34
35 import javax.servlet.SessionTrackingMode;
36 import javax.servlet.http.HttpServletRequest;
37 import javax.servlet.http.HttpSessionEvent;
38 import javax.servlet.http.HttpSessionListener;
39
40 import org.eclipse.jetty.server.SessionIdManager;
41 import org.eclipse.jetty.server.handler.ContextHandler;
42 import org.eclipse.jetty.util.log.Log;
43 import org.eclipse.jetty.util.log.Logger;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public class JDBCSessionManager extends AbstractSessionManager
70 {
71 private static final Logger LOG = Log.getLogger(JDBCSessionManager.class);
72
73 protected String __insertSession;
74 protected String __deleteSession;
75 protected String __selectSession;
76 protected String __updateSession;
77 protected String __updateSessionNode;
78 protected String __updateSessionAccessTime;
79 protected String __sessionTableRowId;
80
81 private ConcurrentHashMap<String, AbstractSession> _sessions;
82 protected long _saveIntervalSec = 60;
83
84
85
86
87
88
89 public class SessionData
90 {
91 private final String _id;
92 private String _rowId;
93 private long _accessed;
94 private long _lastAccessed;
95 private long _maxIdleMs=-1;
96 private long _cookieSet;
97 private long _created;
98 private Map<String,Object> _attributes;
99 private String _lastNode;
100 private String _canonicalContext;
101 private long _lastSaved;
102 private long _expiryTime;
103 private String _virtualHost;
104
105 public SessionData (String sessionId)
106 {
107 _id=sessionId;
108 _created=System.currentTimeMillis();
109 _accessed = _created;
110 _attributes = new HashMap<String,Object>();
111 _lastNode = getSessionIdManager().getWorkerName();
112 }
113
114 public SessionData (String sessionId,Map<String,Object> attributes)
115 {
116 _id=sessionId;
117 _created=System.currentTimeMillis();
118 _accessed = _created;
119 _attributes = attributes;
120 _lastNode = getSessionIdManager().getWorkerName();
121 }
122
123 public synchronized String getId ()
124 {
125 return _id;
126 }
127
128 public synchronized long getCreated ()
129 {
130 return _created;
131 }
132
133 protected synchronized void setCreated (long ms)
134 {
135 _created = ms;
136 }
137
138 public synchronized long getAccessed ()
139 {
140 return _accessed;
141 }
142
143 protected synchronized void setAccessed (long ms)
144 {
145 _accessed = ms;
146 }
147
148
149 public synchronized void setMaxIdleMs (long ms)
150 {
151 _maxIdleMs = ms;
152 }
153
154 public synchronized long getMaxIdleMs()
155 {
156 return _maxIdleMs;
157 }
158
159 public synchronized void setLastAccessed (long ms)
160 {
161 _lastAccessed = ms;
162 }
163
164 public synchronized long getLastAccessed()
165 {
166 return _lastAccessed;
167 }
168
169 public void setCookieSet (long ms)
170 {
171 _cookieSet = ms;
172 }
173
174 public synchronized long getCookieSet ()
175 {
176 return _cookieSet;
177 }
178
179 public synchronized void setRowId (String rowId)
180 {
181 _rowId=rowId;
182 }
183
184 protected synchronized String getRowId()
185 {
186 return _rowId;
187 }
188
189 protected synchronized Map<String,Object> getAttributeMap ()
190 {
191 return _attributes;
192 }
193
194 protected synchronized void setAttributeMap (Map<String,Object> map)
195 {
196 _attributes = map;
197 }
198
199 public synchronized void setLastNode (String node)
200 {
201 _lastNode=node;
202 }
203
204 public synchronized String getLastNode ()
205 {
206 return _lastNode;
207 }
208
209 public synchronized void setCanonicalContext(String str)
210 {
211 _canonicalContext=str;
212 }
213
214 public synchronized String getCanonicalContext ()
215 {
216 return _canonicalContext;
217 }
218
219 public synchronized long getLastSaved ()
220 {
221 return _lastSaved;
222 }
223
224 public synchronized void setLastSaved (long time)
225 {
226 _lastSaved=time;
227 }
228
229 public synchronized void setExpiryTime (long time)
230 {
231 _expiryTime=time;
232 }
233
234 public synchronized long getExpiryTime ()
235 {
236 return _expiryTime;
237 }
238
239 public synchronized void setVirtualHost (String vhost)
240 {
241 _virtualHost=vhost;
242 }
243
244 public synchronized String getVirtualHost ()
245 {
246 return _virtualHost;
247 }
248
249 @Override
250 public String toString ()
251 {
252 return "Session rowId="+_rowId+",id="+_id+",lastNode="+_lastNode+
253 ",created="+_created+",accessed="+_accessed+
254 ",lastAccessed="+_lastAccessed+",cookieSet="+_cookieSet+
255 "lastSaved="+_lastSaved;
256 }
257 }
258
259
260
261
262
263
264
265
266 public class Session extends AbstractSession
267 {
268 private static final long serialVersionUID = 5208464051134226143L;
269 private final SessionData _data;
270 private boolean _dirty=false;
271
272
273
274
275
276
277 protected Session (HttpServletRequest request)
278 {
279 super(JDBCSessionManager.this,request);
280 _data = new SessionData(getClusterId(),_jdbcAttributes);
281 if (_dftMaxIdleSecs>0)
282 _data.setMaxIdleMs(_dftMaxIdleSecs*1000);
283 _data.setCanonicalContext(canonicalize(_context.getContextPath()));
284 _data.setVirtualHost(getVirtualHost(_context));
285 int maxInterval=getMaxInactiveInterval();
286 _data.setExpiryTime(maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000));
287 }
288
289
290
291
292
293 protected Session (long accessed, SessionData data)
294 {
295 super(JDBCSessionManager.this,data.getCreated(), accessed, data.getId());
296 _data=data;
297 if (_dftMaxIdleSecs>0)
298 _data.setMaxIdleMs(_dftMaxIdleSecs*1000);
299 _jdbcAttributes.putAll(_data.getAttributeMap());
300 _data.setAttributeMap(_jdbcAttributes);
301 }
302
303 @Override
304 public void setAttribute (String name, Object value)
305 {
306 super.setAttribute(name, value);
307 _dirty=true;
308 }
309
310 @Override
311 public void removeAttribute (String name)
312 {
313 super.removeAttribute(name);
314 _dirty=true;
315 }
316
317 @Override
318 protected void cookieSet()
319 {
320 _data.setCookieSet(_data.getAccessed());
321 }
322
323
324
325
326
327
328
329 @Override
330 protected boolean access(long time)
331 {
332 if (super.access(time))
333 {
334 _data.setLastAccessed(_data.getAccessed());
335 _data.setAccessed(time);
336
337 int maxInterval=getMaxInactiveInterval();
338 _data.setExpiryTime(maxInterval <= 0 ? 0 : (time + maxInterval*1000));
339 return true;
340 }
341 return false;
342 }
343
344
345
346
347
348 @Override
349 protected void complete()
350 {
351 super.complete();
352 try
353 {
354 if (_dirty)
355 {
356
357
358 willPassivate();
359 updateSession(_data);
360 didActivate();
361 }
362 else if ((_data._accessed - _data._lastSaved) >= (getSaveInterval() * 1000))
363 {
364 updateSessionAccessTime(_data);
365 }
366 }
367 catch (Exception e)
368 {
369 LOG.warn("Problem persisting changed session data id="+getId(), e);
370 }
371 finally
372 {
373 _dirty=false;
374 }
375 }
376
377 @Override
378 protected void timeout() throws IllegalStateException
379 {
380 if (LOG.isDebugEnabled())
381 LOG.debug("Timing out session id="+getClusterId());
382 super.timeout();
383 }
384 }
385
386
387
388
389
390
391
392
393
394 protected class ClassLoadingObjectInputStream extends ObjectInputStream
395 {
396 public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException
397 {
398 super(in);
399 }
400
401 public ClassLoadingObjectInputStream () throws IOException
402 {
403 super();
404 }
405
406 @Override
407 public Class<?> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException
408 {
409 try
410 {
411 return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader());
412 }
413 catch (ClassNotFoundException e)
414 {
415 return super.resolveClass(cl);
416 }
417 }
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 public void setSaveInterval (long sec)
442 {
443 _saveIntervalSec=sec;
444 }
445
446 public long getSaveInterval ()
447 {
448 return _saveIntervalSec;
449 }
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464 public void cacheInvalidate (Session session)
465 {
466
467 }
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486 @Override
487 public Session getSession(String idInCluster)
488 {
489 Session session = (Session)_sessions.get(idInCluster);
490
491 synchronized (this)
492 {
493 try
494 {
495
496
497
498
499
500
501
502
503 SessionData data = null;
504 long now = System.currentTimeMillis();
505 if (LOG.isDebugEnabled())
506 {
507 if (session==null)
508 LOG.debug("getSession("+idInCluster+"): not in session map,"+
509 " now="+now+
510 " lastSaved="+(session==null?0:session._data._lastSaved)+
511 " interval="+(_saveIntervalSec * 1000));
512 else
513 LOG.debug("getSession("+idInCluster+"): in session map, "+
514 " now="+now+
515 " lastSaved="+(session==null?0:session._data._lastSaved)+
516 " interval="+(_saveIntervalSec * 1000)+
517 " lastNode="+session._data.getLastNode()+
518 " thisNode="+getSessionIdManager().getWorkerName()+
519 " difference="+(now - session._data._lastSaved));
520 }
521
522 if (session==null || ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000)))
523 {
524 LOG.debug("getSession("+idInCluster+"): no session in session map or stale session. Reloading session data from db.");
525 data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
526 }
527 else if ((now - session._data._lastSaved) >= (_saveIntervalSec * 1000))
528 {
529 LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db.");
530 data = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context));
531 }
532 else
533 {
534 LOG.debug("getSession("+idInCluster+"): session in session map");
535 data = session._data;
536 }
537
538 if (data != null)
539 {
540 if (!data.getLastNode().equals(getSessionIdManager().getWorkerName()) || session==null)
541 {
542
543 if (data._expiryTime <= 0 || data._expiryTime > now)
544 {
545 LOG.debug("getSession("+idInCluster+"): lastNode="+data.getLastNode()+" thisNode="+getSessionIdManager().getWorkerName());
546 data.setLastNode(getSessionIdManager().getWorkerName());
547
548 session = new Session(now,data);
549 _sessions.put(idInCluster, session);
550 session.didActivate();
551
552
553 updateSessionNode(data);
554 }
555 else
556 if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): Session has expired");
557
558 }
559 else
560 if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): Session not stale "+session._data);
561
562 }
563 else
564 {
565
566 session=null;
567 if (LOG.isDebugEnabled()) LOG.debug("getSession("+idInCluster+"): No session in database matching id="+idInCluster);
568 }
569
570 return session;
571 }
572 catch (Exception e)
573 {
574 LOG.warn("Unable to load session from database", e);
575 return null;
576 }
577 }
578 }
579
580
581
582
583
584
585 @Override
586 public int getSessions()
587 {
588 int size = 0;
589 synchronized (this)
590 {
591 size = _sessions.size();
592 }
593 return size;
594 }
595
596
597
598
599
600
601
602 @Override
603 public void doStart() throws Exception
604 {
605 if (_sessionIdManager==null)
606 throw new IllegalStateException("No session id manager defined");
607
608 prepareTables();
609
610 _sessions = new ConcurrentHashMap<String, AbstractSession>();
611 super.doStart();
612 }
613
614
615
616
617
618
619
620 @Override
621 public void doStop() throws Exception
622 {
623 _sessions.clear();
624 _sessions = null;
625
626 super.doStop();
627 }
628
629 @Override
630 protected void invalidateSessions()
631 {
632
633
634
635
636
637
638 }
639
640
641
642
643
644
645
646 protected void invalidateSession (String idInCluster)
647 {
648 Session session = null;
649 synchronized (this)
650 {
651 session = (Session)_sessions.get(idInCluster);
652 }
653
654 if (session != null)
655 {
656 session.invalidate();
657 }
658 }
659
660
661
662
663
664
665
666 @Override
667 protected boolean removeSession(String idInCluster)
668 {
669 synchronized (this)
670 {
671 Session session = (Session)_sessions.remove(idInCluster);
672 try
673 {
674 if (session != null)
675 deleteSession(session._data);
676 }
677 catch (Exception e)
678 {
679 LOG.warn("Problem deleting session id="+idInCluster, e);
680 }
681 return session!=null;
682 }
683 }
684
685
686
687
688
689
690
691 @Override
692 protected void addSession(AbstractSession session)
693 {
694 if (session==null)
695 return;
696
697 synchronized (this)
698 {
699 _sessions.put(session.getClusterId(), session);
700 }
701
702
703
704 try
705 {
706 session.willPassivate();
707 storeSession(((JDBCSessionManager.Session)session)._data);
708 session.didActivate();
709 }
710 catch (Exception e)
711 {
712 LOG.warn("Unable to store new session id="+session.getId() , e);
713 }
714 }
715
716
717
718
719
720
721
722 @Override
723 protected AbstractSession newSession(HttpServletRequest request)
724 {
725 return new Session(request);
726 }
727
728
729
730
731
732
733
734 @Override
735 public void removeSession(AbstractSession session, boolean invalidate)
736 {
737
738 boolean removed = false;
739
740 synchronized (this)
741 {
742
743 if (getSession(session.getClusterId()) != null)
744 {
745 removed = true;
746 removeSession(session.getClusterId());
747 }
748 }
749
750 if (removed)
751 {
752
753 _sessionIdManager.removeSession(session);
754
755 if (invalidate)
756 _sessionIdManager.invalidateAll(session.getClusterId());
757
758 if (invalidate && !_sessionListeners.isEmpty())
759 {
760 HttpSessionEvent event=new HttpSessionEvent(session);
761 for (HttpSessionListener l : _sessionListeners)
762 l.sessionDestroyed(event);
763 }
764 if (!invalidate)
765 {
766 session.willPassivate();
767 }
768 }
769 }
770
771
772
773
774
775
776
777
778 protected void expire (List<?> sessionIds)
779 {
780
781 if (isStopping() || isStopped())
782 return;
783
784
785 Thread thread=Thread.currentThread();
786 ClassLoader old_loader=thread.getContextClassLoader();
787 ListIterator<?> itor = sessionIds.listIterator();
788
789 try
790 {
791 while (itor.hasNext())
792 {
793 String sessionId = (String)itor.next();
794 if (LOG.isDebugEnabled())
795 LOG.debug("Expiring session id "+sessionId);
796
797 Session session = (Session)_sessions.get(sessionId);
798 if (session != null)
799 {
800 session.timeout();
801 itor.remove();
802 }
803 else
804 {
805 if (LOG.isDebugEnabled())
806 LOG.debug("Unrecognized session id="+sessionId);
807 }
808 }
809 }
810 catch (Throwable t)
811 {
812 if (t instanceof ThreadDeath)
813 throw ((ThreadDeath)t);
814 else
815 LOG.warn("Problem expiring sessions", t);
816 }
817 finally
818 {
819 thread.setContextClassLoader(old_loader);
820 }
821 }
822
823
824 protected void prepareTables ()
825 {
826 __sessionTableRowId = ((JDBCSessionIdManager)_sessionIdManager)._sessionTableRowId;
827
828 __insertSession = "insert into "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
829 " ("+__sessionTableRowId+", sessionId, contextPath, virtualHost, lastNode, accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime, expiryTime, map) "+
830 " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
831
832 __deleteSession = "delete from "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
833 " where "+__sessionTableRowId+" = ?";
834
835 __selectSession = "select * from "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
836 " where sessionId = ? and contextPath = ? and virtualHost = ?";
837
838 __updateSession = "update "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
839 " set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ?, map = ? where "+__sessionTableRowId+" = ?";
840
841 __updateSessionNode = "update "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
842 " set lastNode = ? where "+__sessionTableRowId+" = ?";
843
844 __updateSessionAccessTime = "update "+((JDBCSessionIdManager)_sessionIdManager)._sessionTable+
845 " set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ? where "+__sessionTableRowId+" = ?";
846 }
847
848
849
850
851
852
853
854 protected SessionData loadSession (final String id, final String canonicalContextPath, final String vhost)
855 throws Exception
856 {
857 final AtomicReference<SessionData> _reference = new AtomicReference<SessionData>();
858 final AtomicReference<Exception> _exception = new AtomicReference<Exception>();
859 Runnable load = new Runnable()
860 {
861 @SuppressWarnings("unchecked")
862 public void run()
863 {
864 SessionData data = null;
865 Connection connection=null;
866 PreparedStatement statement = null;
867 try
868 {
869 connection = getConnection();
870 statement = connection.prepareStatement(__selectSession);
871 statement.setString(1, id);
872 statement.setString(2, canonicalContextPath);
873 statement.setString(3, vhost);
874 ResultSet result = statement.executeQuery();
875 if (result.next())
876 {
877 data = new SessionData(id);
878 data.setRowId(result.getString(__sessionTableRowId));
879 data.setCookieSet(result.getLong("cookieTime"));
880 data.setLastAccessed(result.getLong("lastAccessTime"));
881 data.setAccessed (result.getLong("accessTime"));
882 data.setCreated(result.getLong("createTime"));
883 data.setLastNode(result.getString("lastNode"));
884 data.setLastSaved(result.getLong("lastSavedTime"));
885 data.setExpiryTime(result.getLong("expiryTime"));
886 data.setCanonicalContext(result.getString("contextPath"));
887 data.setVirtualHost(result.getString("virtualHost"));
888
889 InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, "map");
890 ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream (is);
891 Object o = ois.readObject();
892 data.setAttributeMap((Map<String,Object>)o);
893 ois.close();
894
895 if (LOG.isDebugEnabled())
896 LOG.debug("LOADED session "+data);
897 }
898 _reference.set(data);
899 }
900 catch (Exception e)
901 {
902 _exception.set(e);
903 }
904 finally
905 {
906 if (connection!=null)
907 {
908 try { connection.close();}
909 catch(Exception e) { LOG.warn(e); }
910 }
911 }
912 }
913 };
914
915 if (_context==null)
916 load.run();
917 else
918 _context.getContextHandler().handle(load);
919
920 if (_exception.get()!=null)
921 throw _exception.get();
922
923 return _reference.get();
924 }
925
926
927
928
929
930
931
932 protected void storeSession (SessionData data)
933 throws Exception
934 {
935 if (data==null)
936 return;
937
938
939 Connection connection = getConnection();
940 PreparedStatement statement = null;
941 try
942 {
943 String rowId = calculateRowId(data);
944
945 long now = System.currentTimeMillis();
946 connection.setAutoCommit(true);
947 statement = connection.prepareStatement(__insertSession);
948 statement.setString(1, rowId);
949 statement.setString(2, data.getId());
950 statement.setString(3, data.getCanonicalContext());
951 statement.setString(4, data.getVirtualHost());
952 statement.setString(5, getSessionIdManager().getWorkerName());
953 statement.setLong(6, data.getAccessed());
954 statement.setLong(7, data.getLastAccessed());
955 statement.setLong(8, data.getCreated());
956 statement.setLong(9, data.getCookieSet());
957 statement.setLong(10, now);
958 statement.setLong(11, data.getExpiryTime());
959
960 ByteArrayOutputStream baos = new ByteArrayOutputStream();
961 ObjectOutputStream oos = new ObjectOutputStream(baos);
962 oos.writeObject(data.getAttributeMap());
963 byte[] bytes = baos.toByteArray();
964
965 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
966 statement.setBinaryStream(12, bais, bytes.length);
967
968 statement.executeUpdate();
969 data.setRowId(rowId);
970 data.setLastSaved(now);
971
972
973 if (LOG.isDebugEnabled())
974 LOG.debug("Stored session "+data);
975 }
976 finally
977 {
978 if (connection!=null)
979 connection.close();
980 }
981 }
982
983
984
985
986
987
988
989
990 protected void updateSession (SessionData data)
991 throws Exception
992 {
993 if (data==null)
994 return;
995
996 Connection connection = getConnection();
997 PreparedStatement statement = null;
998 try
999 {
1000 long now = System.currentTimeMillis();
1001 connection.setAutoCommit(true);
1002 statement = connection.prepareStatement(__updateSession);
1003 statement.setString(1, getSessionIdManager().getWorkerName());
1004 statement.setLong(2, data.getAccessed());
1005 statement.setLong(3, data.getLastAccessed());
1006 statement.setLong(4, now);
1007 statement.setLong(5, data.getExpiryTime());
1008
1009 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1010 ObjectOutputStream oos = new ObjectOutputStream(baos);
1011 oos.writeObject(data.getAttributeMap());
1012 byte[] bytes = baos.toByteArray();
1013 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1014
1015 statement.setBinaryStream(6, bais, bytes.length);
1016 statement.setString(7, data.getRowId());
1017 statement.executeUpdate();
1018
1019 data.setLastSaved(now);
1020 if (LOG.isDebugEnabled())
1021 LOG.debug("Updated session "+data);
1022 }
1023 finally
1024 {
1025 if (connection!=null)
1026 connection.close();
1027 }
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037 protected void updateSessionNode (SessionData data)
1038 throws Exception
1039 {
1040 String nodeId = getSessionIdManager().getWorkerName();
1041 Connection connection = getConnection();
1042 PreparedStatement statement = null;
1043 try
1044 {
1045 connection.setAutoCommit(true);
1046 statement = connection.prepareStatement(__updateSessionNode);
1047 statement.setString(1, nodeId);
1048 statement.setString(2, data.getRowId());
1049 statement.executeUpdate();
1050 statement.close();
1051 if (LOG.isDebugEnabled())
1052 LOG.debug("Updated last node for session id="+data.getId()+", lastNode = "+nodeId);
1053 }
1054 finally
1055 {
1056 if (connection!=null)
1057 connection.close();
1058 }
1059 }
1060
1061
1062
1063
1064
1065
1066
1067 private void updateSessionAccessTime (SessionData data)
1068 throws Exception
1069 {
1070 Connection connection = getConnection();
1071 PreparedStatement statement = null;
1072 try
1073 {
1074 long now = System.currentTimeMillis();
1075 connection.setAutoCommit(true);
1076 statement = connection.prepareStatement(__updateSessionAccessTime);
1077 statement.setString(1, getSessionIdManager().getWorkerName());
1078 statement.setLong(2, data.getAccessed());
1079 statement.setLong(3, data.getLastAccessed());
1080 statement.setLong(4, now);
1081 statement.setLong(5, data.getExpiryTime());
1082 statement.setString(6, data.getRowId());
1083 statement.executeUpdate();
1084 data.setLastSaved(now);
1085 statement.close();
1086 if (LOG.isDebugEnabled())
1087 LOG.debug("Updated access time session id="+data.getId());
1088 }
1089 finally
1090 {
1091 if (connection!=null)
1092 connection.close();
1093 }
1094 }
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106 protected void deleteSession (SessionData data)
1107 throws Exception
1108 {
1109 Connection connection = getConnection();
1110 PreparedStatement statement = null;
1111 try
1112 {
1113 connection.setAutoCommit(true);
1114 statement = connection.prepareStatement(__deleteSession);
1115 statement.setString(1, data.getRowId());
1116 statement.executeUpdate();
1117 if (LOG.isDebugEnabled())
1118 LOG.debug("Deleted Session "+data);
1119 }
1120 finally
1121 {
1122 if (connection!=null)
1123 connection.close();
1124 }
1125 }
1126
1127
1128
1129
1130
1131
1132
1133
1134 private Connection getConnection ()
1135 throws SQLException
1136 {
1137 return ((JDBCSessionIdManager)getSessionIdManager()).getConnection();
1138 }
1139
1140
1141
1142
1143
1144
1145
1146
1147 private String calculateRowId (SessionData data)
1148 {
1149 String rowId = canonicalize(_context.getContextPath());
1150 rowId = rowId + "_" + getVirtualHost(_context);
1151 rowId = rowId+"_"+data.getId();
1152 return rowId;
1153 }
1154
1155
1156
1157
1158
1159
1160
1161
1162 private String getVirtualHost (ContextHandler.Context context)
1163 {
1164 String vhost = "0.0.0.0";
1165
1166 if (context==null)
1167 return vhost;
1168
1169 String [] vhosts = context.getContextHandler().getVirtualHosts();
1170 if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
1171 return vhost;
1172
1173 return vhosts[0];
1174 }
1175
1176
1177
1178
1179
1180
1181
1182 private String canonicalize (String path)
1183 {
1184 if (path==null)
1185 return "";
1186
1187 return path.replace('/', '_').replace('.','_').replace('\\','_');
1188 }
1189 }