/* * Licensed 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.f1x.v1; import org.f1x.api.session.FailedLockException; import org.f1x.api.session.SessionID; import org.f1x.api.session.SessionManager; import java.util.*; /** * Thread safe. */ public class SimpleSessionManager implements SessionManager { protected final Set<SessionID> lockedSessions = new HashSet<>(); protected volatile Map<SessionID, FixSessionAcceptor> sessions = Collections.emptyMap(); protected boolean active = true; @Override public synchronized void addSession(FixSessionAcceptor acceptor) { SessionID sessionID = acceptor.getSessionID(); if (sessions.containsKey(sessionID)) throw new IllegalArgumentException("Session with such session id already exists: " + sessionID); Map<SessionID, FixSessionAcceptor> newSessions = copySessions(); newSessions.put(sessionID, acceptor); this.sessions = newSessions; } @Override public synchronized FixSessionAcceptor removeSession(SessionID sessionID) { FixSessionAcceptor acceptor = null; if (sessions.containsKey(sessionID)) { Map<SessionID, FixSessionAcceptor> newSessions = copySessions(); acceptor = newSessions.remove(sessionID); acceptor.close(); this.sessions = newSessions; } return acceptor; } @Override public FixSessionAcceptor getSession(SessionID sessionID) { return sessions.get(sessionID); } @Override public synchronized FixSessionAcceptor lockSession(SessionID sessionID) throws FailedLockException { checkActive(); FixSessionAcceptor acceptor = sessions.get(sessionID); if (acceptor == null) throw FailedLockException.UNREGISTERED_SESSION_ID; if (lockedSessions.contains(sessionID)) throw FailedLockException.SESSION_ID_IS_ALREADY_USED; lockedSessions.add(sessionID); return acceptor; } @Override public synchronized FixSessionAcceptor unlockSession(SessionID sessionID) { lockedSessions.remove(sessionID); return getSession(sessionID); } @Override public synchronized void close() { if (active) { active = false; for (FixSessionAcceptor acceptor : sessions.values()) acceptor.close(); sessions = Collections.emptyMap(); lockedSessions.clear(); } } protected HashMap<SessionID, FixSessionAcceptor> copySessions() { return new HashMap<>(this.sessions); } protected synchronized void checkActive() throws FailedLockException { if(!active) throw FailedLockException.CLOSED_SESSION_MANAGER; } }