001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    package org.apache.shiro.session.mgt;
020    
021    import java.util.concurrent.Executors;
022    import java.util.concurrent.ScheduledExecutorService;
023    import java.util.concurrent.ThreadFactory;
024    import java.util.concurrent.TimeUnit;
025    
026    import org.slf4j.Logger;
027    import org.slf4j.LoggerFactory;
028    
029    
030    /**
031     * SessionValidationScheduler implementation that uses a
032     * {@link ScheduledExecutorService} to call {@link ValidatingSessionManager#validateSessions()} every
033     * <em>{@link #getInterval interval}</em> milliseconds.
034     *
035     * @author Les Hazlewood
036     * @since 0.9
037     */
038    public class ExecutorServiceSessionValidationScheduler implements SessionValidationScheduler, Runnable {
039    
040        //TODO - complete JavaDoc
041    
042        /** Private internal log instance. */
043        private static final Logger log = LoggerFactory.getLogger(ExecutorServiceSessionValidationScheduler.class);
044    
045        ValidatingSessionManager sessionManager;
046        private ScheduledExecutorService service;
047        private long interval = DefaultSessionManager.DEFAULT_SESSION_VALIDATION_INTERVAL;
048        private boolean enabled = false;
049    
050        public ExecutorServiceSessionValidationScheduler() {
051            super();
052        }
053    
054        public ExecutorServiceSessionValidationScheduler(ValidatingSessionManager sessionManager) {
055            this.sessionManager = sessionManager;
056        }
057    
058        public ValidatingSessionManager getSessionManager() {
059            return sessionManager;
060        }
061    
062        public void setSessionManager(ValidatingSessionManager sessionManager) {
063            this.sessionManager = sessionManager;
064        }
065    
066        public long getInterval() {
067            return interval;
068        }
069    
070        public void setInterval(long interval) {
071            this.interval = interval;
072        }
073    
074        public boolean isEnabled() {
075            return this.enabled;
076        }
077    
078        /**
079         * Creates a single thread {@link ScheduledExecutorService} to validate sessions at fixed intervals 
080         * and enables this scheduler. The executor is created as a daemon thread to allow JVM to shut down
081         */
082        //TODO Implement an integration test to test for jvm exit as part of the standalone example
083        // (so we don't have to change the unit test execution model for the core module)
084        public void enableSessionValidation() {
085            if (this.interval > 0l) {
086                this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {  
087                    public Thread newThread(Runnable r) {  
088                        Thread thread = new Thread(r);  
089                        thread.setDaemon(true);  
090                        return thread;  
091                    }  
092                });                  
093                this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS);
094                this.enabled = true;
095            }
096        }
097    
098        public void run() {
099            if (log.isDebugEnabled()) {
100                log.debug("Executing session validation...");
101            }
102            long startTime = System.currentTimeMillis();
103            this.sessionManager.validateSessions();
104            long stopTime = System.currentTimeMillis();
105            if (log.isDebugEnabled()) {
106                log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds.");
107            }
108        }
109    
110        public void disableSessionValidation() {
111            this.service.shutdownNow();
112            this.enabled = false;
113        }
114    }