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