1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.shiro.session.mgt.quartz;
20
21 import org.quartz.JobBuilder;
22 import org.quartz.JobDetail;
23 import org.quartz.Scheduler;
24 import org.quartz.SchedulerException;
25 import org.quartz.SimpleTrigger;
26 import org.quartz.TriggerBuilder;
27 import org.quartz.TriggerKey;
28 import org.quartz.impl.StdSchedulerFactory;
29
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import org.apache.shiro.session.mgt.DefaultSessionManager;
34 import org.apache.shiro.session.mgt.SessionValidationScheduler;
35 import org.apache.shiro.session.mgt.ValidatingSessionManager;
36
37 import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
38
39
40
41
42
43
44
45
46
47 public class QuartzSessionValidationScheduler implements SessionValidationScheduler {
48
49
50
51
52
53
54
55
56
57
58 public static final long DEFAULT_SESSION_VALIDATION_INTERVAL = DefaultSessionManager.DEFAULT_SESSION_VALIDATION_INTERVAL;
59
60
61
62
63 private static final String JOB_NAME = "SessionValidationJob";
64
65
66
67
68 private static final Logger log = LoggerFactory.getLogger(QuartzSessionValidationScheduler.class);
69
70
71
72
73
74 private Scheduler scheduler;
75
76 private boolean schedulerImplicitlyCreated = false;
77
78 private boolean enabled = false;
79
80
81
82
83 private ValidatingSessionManager sessionManager;
84
85
86
87
88 private long sessionValidationInterval = DEFAULT_SESSION_VALIDATION_INTERVAL;
89
90
91
92
93
94
95
96
97 public QuartzSessionValidationScheduler() {
98 }
99
100
101
102
103
104
105 public QuartzSessionValidationScheduler(ValidatingSessionManager sessionManager) {
106 this.sessionManager = sessionManager;
107 }
108
109
110
111
112
113 protected Scheduler getScheduler() throws SchedulerException {
114 if (scheduler == null) {
115 scheduler = StdSchedulerFactory.getDefaultScheduler();
116 schedulerImplicitlyCreated = true;
117 }
118 return scheduler;
119 }
120
121 public void setScheduler(Scheduler scheduler) {
122 this.scheduler = scheduler;
123 }
124
125 public void setSessionManager(ValidatingSessionManager sessionManager) {
126 this.sessionManager = sessionManager;
127 }
128
129 public boolean isEnabled() {
130 return this.enabled;
131 }
132
133
134
135
136
137
138
139
140
141 public void setSessionValidationInterval(long sessionValidationInterval) {
142 this.sessionValidationInterval = sessionValidationInterval;
143 }
144
145
146
147
148
149
150
151
152
153 public void enableSessionValidation() {
154
155 if (log.isDebugEnabled()) {
156 log.debug("Scheduling session validation job using Quartz with " +
157 "session validation interval of [" + sessionValidationInterval + "]ms...");
158 }
159
160 try {
161 TriggerBuilder<SimpleTrigger> triggerBuilder =
162 TriggerBuilder.newTrigger()
163 .withIdentity(getClass().getName(), Scheduler.DEFAULT_GROUP)
164 .withSchedule(simpleSchedule()
165 .withIntervalInMilliseconds(sessionValidationInterval)
166 .withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY));
167 SimpleTrigger trigger = triggerBuilder.build();
168
169 JobDetail detail = JobBuilder.newJob(QuartzSessionValidationJob.class)
170 .withIdentity(JOB_NAME, Scheduler.DEFAULT_GROUP).build();
171 detail.getJobDataMap().put(QuartzSessionValidationJob.SESSION_MANAGER_KEY, sessionManager);
172
173 Scheduler scheduler = getScheduler();
174
175 scheduler.scheduleJob(detail, trigger);
176 if (schedulerImplicitlyCreated) {
177 scheduler.start();
178 if (log.isDebugEnabled()) {
179 log.debug("Successfully started implicitly created Quartz Scheduler instance.");
180 }
181 }
182 this.enabled = true;
183
184 if (log.isDebugEnabled()) {
185 log.debug("Session validation job successfully scheduled with Quartz.");
186 }
187
188 } catch (SchedulerException e) {
189 if (log.isErrorEnabled()) {
190 log.error("Error starting the Quartz session validation job. Session validation may not occur.", e);
191 }
192 }
193 }
194
195 public void disableSessionValidation() {
196 if (log.isDebugEnabled()) {
197 log.debug("Stopping Quartz session validation job...");
198 }
199
200 Scheduler scheduler;
201 try {
202 scheduler = getScheduler();
203 if (scheduler == null) {
204 if (log.isWarnEnabled()) {
205 log.warn("getScheduler() method returned a null Quartz scheduler, which is unexpected. Please " +
206 "check your configuration and/or implementation. Returning quietly since there is no " +
207 "validation job to remove (scheduler does not exist).");
208 }
209 return;
210 }
211 } catch (SchedulerException e) {
212 if (log.isWarnEnabled()) {
213 log.warn("Unable to acquire Quartz Scheduler. Ignoring and returning (already stopped?)", e);
214 }
215 return;
216 }
217
218 try {
219 scheduler.unscheduleJob(TriggerKey.triggerKey(JOB_NAME, Scheduler.DEFAULT_GROUP));
220 if (log.isDebugEnabled()) {
221 log.debug("Quartz session validation job stopped successfully.");
222 }
223 } catch (SchedulerException e) {
224 if (log.isDebugEnabled()) {
225 log.debug("Could not cleanly remove SessionValidationJob from Quartz scheduler. " +
226 "Ignoring and stopping.", e);
227 }
228 }
229
230 this.enabled = false;
231
232 if (schedulerImplicitlyCreated) {
233 try {
234 scheduler.shutdown();
235 } catch (SchedulerException e) {
236 if (log.isWarnEnabled()) {
237 log.warn("Unable to cleanly shutdown implicitly created Quartz Scheduler instance.", e);
238 }
239 } finally {
240 setScheduler(null);
241 schedulerImplicitlyCreated = false;
242 }
243 }
244
245
246 }
247 }