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 public class QuartzSessionValidationScheduler implements SessionValidationScheduler {
47
48
49
50
51
52
53
54
55
56
57 public static final long DEFAULT_SESSION_VALIDATION_INTERVAL = DefaultSessionManager.DEFAULT_SESSION_VALIDATION_INTERVAL;
58
59
60
61
62 private static final String JOB_NAME = "SessionValidationJob";
63
64
65
66
67 private static final Logger LOGGER = LoggerFactory.getLogger(QuartzSessionValidationScheduler.class);
68
69
70
71
72
73 private Scheduler scheduler;
74
75 private boolean schedulerImplicitlyCreated;
76
77 private boolean enabled;
78
79
80
81
82 private ValidatingSessionManager sessionManager;
83
84
85
86
87 private long sessionValidationInterval = DEFAULT_SESSION_VALIDATION_INTERVAL;
88
89
90
91
92
93
94
95
96 public QuartzSessionValidationScheduler() {
97 }
98
99
100
101
102
103
104 public QuartzSessionValidationScheduler(ValidatingSessionManager sessionManager) {
105 this.sessionManager = sessionManager;
106 }
107
108
109
110
111
112 protected Scheduler getScheduler() throws SchedulerException {
113 if (scheduler == null) {
114 scheduler = StdSchedulerFactory.getDefaultScheduler();
115 schedulerImplicitlyCreated = true;
116 }
117 return scheduler;
118 }
119
120 public void setScheduler(Scheduler scheduler) {
121 this.scheduler = scheduler;
122 }
123
124 public void setSessionManager(ValidatingSessionManager sessionManager) {
125 this.sessionManager = sessionManager;
126 }
127
128 public boolean isEnabled() {
129 return this.enabled;
130 }
131
132
133
134
135
136
137
138
139
140 public void setSessionValidationInterval(long sessionValidationInterval) {
141 this.sessionValidationInterval = sessionValidationInterval;
142 }
143
144
145
146
147
148
149
150
151
152 public void enableSessionValidation() {
153
154 if (LOGGER.isDebugEnabled()) {
155 LOGGER.debug("Scheduling session validation job using Quartz with "
156 + "session validation interval of [" + sessionValidationInterval + "]ms...");
157 }
158
159 try {
160 TriggerBuilder<SimpleTrigger> triggerBuilder =
161 TriggerBuilder.newTrigger()
162 .withIdentity(getClass().getName(), Scheduler.DEFAULT_GROUP)
163 .withSchedule(simpleSchedule()
164 .withIntervalInMilliseconds(sessionValidationInterval)
165 .withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY));
166 SimpleTrigger trigger = triggerBuilder.build();
167
168 JobDetail detail = JobBuilder.newJob(QuartzSessionValidationJob.class)
169 .withIdentity(JOB_NAME, Scheduler.DEFAULT_GROUP).build();
170 detail.getJobDataMap().put(QuartzSessionValidationJob.SESSION_MANAGER_KEY, sessionManager);
171
172 Scheduler scheduler = getScheduler();
173
174 scheduler.scheduleJob(detail, trigger);
175 if (schedulerImplicitlyCreated) {
176 scheduler.start();
177 if (LOGGER.isDebugEnabled()) {
178 LOGGER.debug("Successfully started implicitly created Quartz Scheduler instance.");
179 }
180 }
181 this.enabled = true;
182
183 if (LOGGER.isDebugEnabled()) {
184 LOGGER.debug("Session validation job successfully scheduled with Quartz.");
185 }
186
187 } catch (SchedulerException e) {
188 if (LOGGER.isErrorEnabled()) {
189 LOGGER.error("Error starting the Quartz session validation job. Session validation may not occur.", e);
190 }
191 }
192 }
193
194 @SuppressWarnings("checkstyle:NPathComplexity")
195 public void disableSessionValidation() {
196 if (LOGGER.isDebugEnabled()) {
197 LOGGER.debug("Stopping Quartz session validation job...");
198 }
199
200 Scheduler scheduler;
201 try {
202 scheduler = getScheduler();
203 if (scheduler == null) {
204 if (LOGGER.isWarnEnabled()) {
205 LOGGER.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 (LOGGER.isWarnEnabled()) {
213 LOGGER.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 (LOGGER.isDebugEnabled()) {
221 LOGGER.debug("Quartz session validation job stopped successfully.");
222 }
223 } catch (SchedulerException e) {
224 if (LOGGER.isDebugEnabled()) {
225 LOGGER.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 (LOGGER.isWarnEnabled()) {
237 LOGGER.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 }