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