/* * TeleStax, Open Source Cloud Communications * Copyright 2011-2016, TeleStax Inc. and individual contributors * by the @authors tag. * * This program is free software: you can redistribute it and/or modify * under the terms of the GNU Affero General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> * * This file incorporates work covered by the following copyright and * permission notice: * * JBoss, Home of Professional Open Source * Copyright 2007-2011, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jdiameter.common.impl.data; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; import org.jdiameter.api.BaseSession; import org.jdiameter.api.NetworkReqListener; import org.jdiameter.client.api.IContainer; import org.jdiameter.client.api.ISession; import org.jdiameter.common.api.app.IAppSessionData; import org.jdiameter.common.api.app.IAppSessionDataFactory; import org.jdiameter.common.api.app.acc.IAccSessionData; import org.jdiameter.common.api.app.auth.IAuthSessionData; import org.jdiameter.common.api.app.cca.ICCASessionData; import org.jdiameter.common.api.app.cxdx.ICxDxSessionData; import org.jdiameter.common.api.app.gx.IGxSessionData; import org.jdiameter.common.api.app.rf.IRfSessionData; import org.jdiameter.common.api.app.ro.IRoSessionData; import org.jdiameter.common.api.app.rx.IRxSessionData; import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.common.api.app.s6a.IS6aSessionData; import org.jdiameter.common.api.app.sh.IShSessionData; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.acc.AccLocalSessionDataFactory; import org.jdiameter.common.impl.app.auth.AuthLocalSessionDataFactory; import org.jdiameter.common.impl.app.cca.CCALocalSessionDataFactory; import org.jdiameter.common.impl.app.cxdx.CxDxLocalSessionDataFactory; import org.jdiameter.common.impl.app.gx.GxLocalSessionDataFactory; import org.jdiameter.common.impl.app.rf.RfLocalSessionDataFactory; import org.jdiameter.common.impl.app.ro.RoLocalSessionDataFactory; import org.jdiameter.common.impl.app.rx.RxLocalSessionDataFactory; import org.jdiameter.common.impl.app.s13.S13LocalSessionDataFactory; import org.jdiameter.common.impl.app.s6a.S6aLocalSessionDataFactory; import org.jdiameter.common.impl.app.sh.ShLocalSessionDataFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Local implementation of session datasource for {@link ISessionDatasource} * * @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a> * @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a> */ public class LocalDataSource implements ISessionDatasource { //provided by impl, no way to change that, no conf! :) protected HashMap<Class<? extends IAppSessionData>, IAppSessionDataFactory<? extends IAppSessionData>> appSessionDataFactories = new HashMap<Class<? extends IAppSessionData>, IAppSessionDataFactory<? extends IAppSessionData>>(); private ConcurrentHashMap<String, SessionEntry> sessionIdToEntry = new ConcurrentHashMap<String, LocalDataSource.SessionEntry>(); private static final Logger logger = LoggerFactory.getLogger(LocalDataSource.class); public LocalDataSource() { appSessionDataFactories.put(ICCASessionData.class, new CCALocalSessionDataFactory()); appSessionDataFactories.put(IRoSessionData.class, new RoLocalSessionDataFactory()); appSessionDataFactories.put(IRfSessionData.class, new RfLocalSessionDataFactory()); appSessionDataFactories.put(IGxSessionData.class, new GxLocalSessionDataFactory()); appSessionDataFactories.put(IAccSessionData.class, new AccLocalSessionDataFactory()); appSessionDataFactories.put(IAuthSessionData.class, new AuthLocalSessionDataFactory()); appSessionDataFactories.put(IShSessionData.class, new ShLocalSessionDataFactory()); appSessionDataFactories.put(ICxDxSessionData.class, new CxDxLocalSessionDataFactory()); appSessionDataFactories.put(IRxSessionData.class, new RxLocalSessionDataFactory()); appSessionDataFactories.put(IS6aSessionData.class, new S6aLocalSessionDataFactory()); appSessionDataFactories.put(IS13SessionData.class, new S13LocalSessionDataFactory()); } public LocalDataSource(IContainer container) { this(); } @Override public boolean exists(String sessionId) { return this.sessionIdToEntry.containsKey(sessionId); } @Override public void setSessionListener(String sessionId, NetworkReqListener data) { logger.debug("setSessionListener({}, {})", sessionId, data); SessionEntry se = sessionIdToEntry.get(sessionId); if (se != null) { se.listener = data; } else { throw new IllegalArgumentException("No Session entry for id: " + sessionId); } } @Override public NetworkReqListener getSessionListener(String sessionId) { SessionEntry se = sessionIdToEntry.get(sessionId); logger.debug("getSessionListener({}) => {}", sessionId, se); return se != null ? se.listener : null; } @Override public NetworkReqListener removeSessionListener(String sessionId) { SessionEntry se = sessionIdToEntry.get(sessionId); logger.debug("removeSessionListener({}) => {}", sessionId, se); if (se != null) { NetworkReqListener lst = se.listener; se.listener = null; return lst; } else { return null; } } @Override public void addSession(BaseSession session) { logger.debug("addSession({})", session); SessionEntry se = null; String sessionId = session.getSessionId(); //FIXME: check here replicable vs not replicable? if (this.sessionIdToEntry.containsKey(sessionId)) { se = this.sessionIdToEntry.get(sessionId); if ( !(se.session instanceof ISession) || se.session.isReplicable()) { //must be not replicable so we can "overwrite" throw new IllegalArgumentException("Sessin with id: " + sessionId + ", already exists!"); } else { this.sessionIdToEntry.put(sessionId, se); } } else { se = new SessionEntry(); } se.session = session; this.sessionIdToEntry.put(session.getSessionId(), se); } @Override public BaseSession getSession(String sessionId) { SessionEntry se = sessionIdToEntry.get(sessionId); logger.debug("getSession({}) => {}", sessionId, se); return se != null ? se.session : null; } @Override public void removeSession(String sessionId) { SessionEntry se = this.sessionIdToEntry.remove(sessionId); logger.debug("removeSession({}) => {}", sessionId, se); } /* (non-Javadoc) * @see org.jdiameter.common.api.data.ISessionDatasource#start() */ @Override public void start() { // NOP } /* (non-Javadoc) * @see org.jdiameter.common.api.data.ISessionDatasource#stop() */ @Override public void stop() { // NOP } /* (non-Javadoc) * @see org.jdiameter.common.api.data.ISessionDatasource#isClustered() */ @Override public boolean isClustered() { return false; } @Override public String toString() { return "LocalDataSource [sessionIdToEntry=" + sessionIdToEntry + "]"; } //simple class to reduce collections overhead. private class SessionEntry { BaseSession session; NetworkReqListener listener; @Override public String toString() { return "SessionEntry [session=" + session + ", listener=" + listener + "]"; } } /* * (non-Javadoc) * * @see * org.jdiameter.common.api.data.ISessionDatasource#getDataFactory(java. * lang.Class) */ @Override public IAppSessionDataFactory<? extends IAppSessionData> getDataFactory(Class<? extends IAppSessionData> x) { return this.appSessionDataFactories.get(x); } }