All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.openejb.server.httpd.session.SessionManager Maven / Gradle / Ivy

There is a newer version: 7.1.0
Show newest version
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.openejb.server.httpd.session;

import org.apache.openejb.core.WebContext;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.server.httpd.BeginWebBeansListener;
import org.apache.openejb.server.httpd.EndWebBeansListener;
import org.apache.openejb.server.httpd.HttpSession;
import org.apache.openejb.util.DaemonThreadFactory;
import org.apache.openejb.util.Duration;
import org.apache.webbeans.config.WebBeansContext;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpSessionEvent;

public class SessionManager {
    public static final String EJBSESSIONID = "EJBSESSIONID";
    public static final String JSESSIONID = "JSESSIONID";

    private final ConcurrentMap sessions = new ConcurrentHashMap<>();

    private static volatile ScheduledExecutorService es;

    public void destroy(final WebContext app) {
        if (app == null) {
            return;
        }

        final Thread tc = Thread.currentThread();
        final ClassLoader tccl = tc.getContextClassLoader();
        tc.setContextClassLoader(app.getClassLoader());
        try {
            final Iterator iterator = sessions.values().iterator();
            while (iterator.hasNext()) {
                final SessionWrapper next = iterator.next();
                if (next.app == app) {
                    doDestroy(next);
                    iterator.remove();
                }
            }
        } finally {
            tc.setContextClassLoader(tccl);
        }
    }

    private void doDestroy(final SessionWrapper next) {
        HttpSessionEvent event = null;
        if (next.end != null) {
            event = new HttpSessionEvent(next.session);
            next.end.sessionDestroyed(event);
            next.begin.sessionCreated(event); // just set session thread local
        }
        try {
            next.session.invalidate();
        } finally {
            if (next.begin != null) {
                next.begin.sessionDestroyed(event);
            }
        }
    }

    public void destroy() {
        if (es == null) {
            return;
        }
        es.shutdownNow();
        for (final SessionWrapper rs : sessions.values()) {
            rs.session.invalidate();
        }
        sessions.clear();
    }

    public void initEviction() {
        if (!"true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.http.eviction", "true"))) {
            return;
        }
        final Duration duration = new Duration(SystemInstance.get().getProperty("openejb.http.eviction.duration", "1 minute"));
        es = Executors.newScheduledThreadPool(1, new DaemonThreadFactory(SessionManager.class));
        es.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                for (final SessionWrapper data : new ArrayList<>(sessions.values())) {
                    final HttpSession session = data.session;
                    if (session.getMaxInactiveInterval() > 0
                            && session.getLastAccessedTime() + TimeUnit.SECONDS.toMillis(session.getMaxInactiveInterval()) < System.currentTimeMillis()) {
                        doDestroy(data);
                        sessions.remove(data.session.getId());
                    }
                }
            }
        }, duration.getTime(), duration.getTime(), duration.getUnit());
    }

    public SessionWrapper findSession(final String id) {
        return sessions.get(id);
    }

    public void removeSession(final String sessionId) {
        sessions.remove(sessionId);
    }

    public Collection findSessionIds() {
        return sessions.keySet();
    }

    public int size() {
        return sessions.size();
    }

    public SessionWrapper newSession(final BeginWebBeansListener begin, final EndWebBeansListener end,
                                     final HttpSession session, final WebContext app) {
        final SessionWrapper wrapper = new SessionWrapper(begin, end, session, app);
        final SessionWrapper existing = sessions.putIfAbsent(session.getId(), wrapper);
        if (existing == null && es == null) {
            synchronized (this) {
                if (es == null) {
                    initEviction();
                }
            }
        }
        return existing == null ? wrapper : existing;
    }

    public static class SessionWrapper extends HttpSessionEvent {
        public final BeginWebBeansListener begin;
        public final EndWebBeansListener end;
        public final HttpSession session;
        public final WebContext app;

        public SessionWrapper(final BeginWebBeansListener begin, final EndWebBeansListener end, final HttpSession session, final WebContext app) {
            super(session);
            this.begin = begin;
            this.end = end;
            this.session = session;
            this.app = app;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy