/*
* Mobicents, Communications Middleware
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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 Lesser General Public License
* for more details.
*
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
*
* Boston, MA 02110-1301 USA
*/
package org.mobicents.slee.resource.diameter.base;
import static org.jdiameter.client.impl.helpers.Parameters.MessageTimeOut;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.management.ObjectName;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import javax.slee.Address;
import javax.slee.facilities.EventLookupFacility;
import javax.slee.management.UnrecognizedResourceAdaptorEntityException;
import javax.slee.resource.ActivityHandle;
import javax.slee.resource.BootstrapContext;
import javax.slee.resource.FailureReason;
import javax.slee.resource.Marshaler;
import javax.slee.resource.ResourceAdaptor;
import javax.slee.resource.ResourceAdaptorTypeID;
import javax.slee.resource.ResourceException;
import javax.slee.resource.SleeEndpoint;
import net.java.slee.resource.diameter.base.AccountingClientSessionActivity;
import net.java.slee.resource.diameter.base.AccountingServerSessionActivity;
import net.java.slee.resource.diameter.base.AuthClientSessionActivity;
import net.java.slee.resource.diameter.base.AuthServerSessionActivity;
import net.java.slee.resource.diameter.base.CreateActivityException;
import net.java.slee.resource.diameter.base.DiameterActivity;
import net.java.slee.resource.diameter.base.DiameterActivityContextInterfaceFactory;
import net.java.slee.resource.diameter.base.DiameterAvpFactory;
import net.java.slee.resource.diameter.base.DiameterMessageFactory;
import net.java.slee.resource.diameter.base.DiameterProvider;
import net.java.slee.resource.diameter.base.events.AbortSessionAnswer;
import net.java.slee.resource.diameter.base.events.AccountingAnswer;
import net.java.slee.resource.diameter.base.events.CapabilitiesExchangeAnswer;
import net.java.slee.resource.diameter.base.events.DeviceWatchdogAnswer;
import net.java.slee.resource.diameter.base.events.DiameterMessage;
import net.java.slee.resource.diameter.base.events.DisconnectPeerAnswer;
import net.java.slee.resource.diameter.base.events.ErrorAnswer;
import net.java.slee.resource.diameter.base.events.ReAuthAnswer;
import net.java.slee.resource.diameter.base.events.SessionTerminationAnswer;
import net.java.slee.resource.diameter.base.events.avp.AvpNotAllowedException;
import net.java.slee.resource.diameter.base.events.avp.DiameterAvpCodes;
import net.java.slee.resource.diameter.base.events.avp.DiameterIdentity;
import org.apache.log4j.Logger;
import org.jdiameter.api.Answer;
import org.jdiameter.api.ApplicationId;
import org.jdiameter.api.Avp;
import org.jdiameter.api.AvpDataException;
import org.jdiameter.api.AvpSet;
import org.jdiameter.api.IllegalDiameterStateException;
import org.jdiameter.api.InternalException;
import org.jdiameter.api.Message;
import org.jdiameter.api.Peer;
import org.jdiameter.api.PeerTable;
import org.jdiameter.api.RawSession;
import org.jdiameter.api.Request;
import org.jdiameter.api.Session;
import org.jdiameter.api.SessionFactory;
import org.jdiameter.api.Stack;
import org.jdiameter.api.acc.ClientAccSession;
import org.jdiameter.api.acc.ServerAccSession;
import org.jdiameter.api.app.AppSession;
import org.jdiameter.api.auth.ClientAuthSession;
import org.jdiameter.api.auth.ServerAuthSession;
import org.jdiameter.client.api.ISessionFactory;
import org.jdiameter.client.impl.app.acc.ClientAccSessionImpl;
import org.jdiameter.client.impl.app.auth.ClientAuthSessionImpl;
import org.jdiameter.common.impl.validation.JAvpNotAllowedException;
import org.jdiameter.server.impl.app.acc.ServerAccSessionImpl;
import org.jdiameter.server.impl.app.auth.ServerAuthSessionImpl;
import org.mobicents.diameter.stack.DiameterListener;
import org.mobicents.diameter.stack.DiameterStackMultiplexerMBean;
import org.mobicents.slee.container.SleeContainer;
import org.mobicents.slee.resource.ResourceAdaptorActivityContextInterfaceFactory;
import org.mobicents.slee.resource.ResourceAdaptorEntity;
import org.mobicents.slee.resource.ResourceAdaptorState;
import org.mobicents.slee.resource.diameter.base.events.AbortSessionAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.AbortSessionRequestImpl;
import org.mobicents.slee.resource.diameter.base.events.AccountingAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.AccountingRequestImpl;
import org.mobicents.slee.resource.diameter.base.events.CapabilitiesExchangeAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.CapabilitiesExchangeRequestImpl;
import org.mobicents.slee.resource.diameter.base.events.DeviceWatchdogAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.DeviceWatchdogRequestImpl;
import org.mobicents.slee.resource.diameter.base.events.DiameterMessageImpl;
import org.mobicents.slee.resource.diameter.base.events.DisconnectPeerAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.DisconnectPeerRequestImpl;
import org.mobicents.slee.resource.diameter.base.events.ErrorAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.ExtensionDiameterMessageImpl;
import org.mobicents.slee.resource.diameter.base.events.ReAuthAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.ReAuthRequestImpl;
import org.mobicents.slee.resource.diameter.base.events.SessionTerminationAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.SessionTerminationRequestImpl;
import org.mobicents.slee.resource.diameter.base.handlers.AccountingSessionFactory;
import org.mobicents.slee.resource.diameter.base.handlers.AuthorizationSessionFactory;
import org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener;
/**
* Diameter Base Resource Adaptor
*
* <br>
* Super project: mobicents <br>
* 1:20:00 AM May 9, 2008 <br>
*
* @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
* @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
* @author Erick Svenson
*/
public class DiameterBaseResourceAdaptor implements ResourceAdaptor, DiameterListener, BaseSessionCreationListener {
private static final long serialVersionUID = 1L;
private static transient Logger logger = Logger.getLogger(DiameterBaseResourceAdaptor.class);
private ResourceAdaptorState state;
private Stack stack;
private SessionFactory sessionFactory = null;
private long messageTimeout = 5000;
//private DiameterStackMultiplexerProxyMBeanImpl proxy=new DiameterStackMultiplexerProxyMBeanImpl();
private ObjectName diameterMultiplexerObjectName = null;
private DiameterStackMultiplexerMBean diameterMux=null;
private DiameterAvpFactoryImpl diameterAvpFactory = new DiameterAvpFactoryImpl();
/**
* The BootstrapContext provides the resource adaptor with the required
* capabilities in the SLEE to execute its work. The bootstrap context is
* implemented by the SLEE. The BootstrapContext object holds references to
* a number of objects that are of interest to many resource adaptors. For
* further information see JSLEE v1.1 Specification Page 305. The
* bootstrapContext will be set in entityCreated() method.
*/
private transient BootstrapContext bootstrapContext = null;
/**
* The SLEE endpoint defines the contract between the SLEE and the resource
* adaptor that enables the resource adaptor to deliver events
* asynchronously to SLEE endpoints residing in the SLEE. This contract
* serves as a generic contract that allows a wide range of resources to be
* plugged into a SLEE environment via the resource adaptor architecture.
* For further information see JSLEE v1.1 Specification Page 307 The
* sleeEndpoint will be initialized in entityCreated() method.
*/
private transient SleeEndpoint sleeEndpoint = null;
/**
* the EventLookupFacility is used to look up the event id of incoming
* events
*/
private transient EventLookupFacility eventLookup = null;
/**
* The list of activites stored in this resource adaptor. If this resource
* adaptor were a distributed and highly available solution, this storage
* were one of the candidates for distribution.
*/
private transient ConcurrentHashMap<ActivityHandle, DiameterActivity> activities = null;
/**
* The activity context interface factory defined in
* DiameterRAActivityContextInterfaceFactoryImpl
*/
private transient DiameterActivityContextInterfaceFactory acif = null;
/**
* A link to the DiameterProvider which then will be exposed to Sbbs
*/
private transient DiameterProviderImpl raProvider = null;
protected transient AuthorizationSessionFactory authSessionFactory=null;
protected transient AccountingSessionFactory accSessionFactory=null;
protected transient SessionFactory proxySessionFactory=null;
/**
* Holds code to name
*/
private static final Map<Integer, String> events;
private static HashSet<Integer> accEventCodes = new HashSet<Integer>();
private static HashSet<Integer> authEventCodes = new HashSet<Integer>();
//private static final Map<String,Integer> evenName2EventID = new HashMap<String, Integer>();
static
{
Map<Integer, String> eventsTemp = new HashMap<Integer, String>();
eventsTemp.put(AbortSessionAnswer.commandCode, "AbortSession");
eventsTemp.put(AccountingAnswer.commandCode, "Accounting");
eventsTemp.put(CapabilitiesExchangeAnswer.commandCode, "CapabilitiesExchange");
eventsTemp.put(DeviceWatchdogAnswer.commandCode, "DeviceWatchdog");
eventsTemp.put(DisconnectPeerAnswer.commandCode, "DisconnectPeer");
eventsTemp.put(ReAuthAnswer.commandCode, "ReAuth");
eventsTemp.put(SessionTerminationAnswer.commandCode, "SessionTermination");
eventsTemp.put(ErrorAnswer.commandCode, "Error");
// FIXME: baranowb - make sure its compilant with xml
//eventsTemp.put(ExtensionDiameterMessage.commandCode, "ExtensionDiameter");
events = Collections.unmodifiableMap(eventsTemp);
authEventCodes.add(AbortSessionAnswer.commandCode);
authEventCodes.add(ReAuthAnswer.commandCode);
authEventCodes.add(SessionTerminationAnswer.commandCode);
accEventCodes.add(AccountingAnswer.commandCode);
}
public DiameterBaseResourceAdaptor()
{
logger.info("Diameter Base RA :: DiameterBaseResourceAdaptor.");
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 301 for further information. <br>
* The SLEE calls this method to inform the resource adaptor that the SLEE
* has completed activity end processing for the activity represented by the
* activity handle. The resource adaptor should release any resource related
* to this activity as the SLEE will not ask for it again.
*/
public void activityEnded(ActivityHandle handle)
{
logger.info("Diameter Base RA :: activityEnded :: handle[" + handle + ".");
if(this.activities != null)
{
synchronized (this.activities)
{
this.activities.remove(handle);
}
}
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 301 for further information. <br>
* The SLEE calls this method to inform the resource adaptor that the
* activitys Activity Context object is no longer attached to any SBB
* entities and is no longer referenced by any SLEE Facilities. This enables
* the resource adaptor to implicitly end the Activity object.
*/
public void activityUnreferenced(ActivityHandle handle)
{
logger.info("Diameter Base RA :: activityUnreferenced :: handle[" + handle + "].");
this.activityEnded(handle);
}
/**
* implements javax.slee.resource.ResourceAdaptor The JSLEE v1.1
* Specification does not include entityActivated(). However, the API
* description of JSLEE v1.1 does include this method already. So, the
* documentation follows the code. <br>
* This method is called in context of project Mobicents in context of
* resource adaptor activation. More precisely,
* org.mobicents.slee.resource.ResourceAdaptorEntity.activate() calls this
* method entityActivated(). This method signals the resource adaptor the
* transition from state "INACTIVE" to state "ACTIVE".
*/
public void entityActivated() throws ResourceException
{
logger.info("Diameter Base RA :: entityActivated.");
try
{
logger.info("Activating Diameter Base RA Entity");
this.diameterMultiplexerObjectName=new ObjectName("diameter.mobicents:service=DiameterStackMultiplexer");
Object[] params = new Object[]{};
String[] signature = new String[]{};
String operation = "getMultiplexerMBean";
Object object = SleeContainer.lookupFromJndi().getMBeanServer().invoke( this.diameterMultiplexerObjectName, operation, params, signature );
if(object instanceof DiameterStackMultiplexerMBean)
this.diameterMux = (DiameterStackMultiplexerMBean) object;
this.raProvider = new DiameterProviderImpl(this);
initializeNamingContext();
this.activities = new ConcurrentHashMap();
this.state = ResourceAdaptorState.CONFIGURED;
// Initialize the protocol stack
initStack();
// Resource Adaptor ready to rumble!
this.state = ResourceAdaptorState.ACTIVE;
this.sessionFactory = this.stack.getSessionFactory();
this.accSessionFactory = AccountingSessionFactory.INSTANCE;
this.accSessionFactory.registerListener(this, messageTimeout, sessionFactory);
this.authSessionFactory=new AuthorizationSessionFactory(this,messageTimeout,sessionFactory);
//this.proxySessionFactory=this.sessionFactory;
this.proxySessionFactory = new SessionFactory() {
public <T extends AppSession> T getNewAppSession(ApplicationId applicationId, Class<? extends AppSession> userSession) throws InternalException
{
return (T)sessionFactory.getNewAppSession(applicationId, userSession);
}
public <T extends AppSession> T getNewAppSession(String sessionId, ApplicationId applicationId, Class<? extends AppSession> userSession) throws InternalException
{
return (T)sessionFactory.getNewAppSession(sessionId, applicationId, userSession);
}
public RawSession getNewRawSession() throws InternalException
{
try
{
return stack.getSessionFactory().getNewRawSession();
}
catch ( IllegalDiameterStateException e )
{
logger.error( "Failure while obtaining Session Factory for new Raw Session.", e );
return null;
}
}
public Session getNewSession() throws InternalException
{
Session session = sessionFactory.getNewSession();
sessionCreated(session);
return session;
}
public Session getNewSession(String sessionId) throws InternalException
{
Session session=sessionFactory.getNewSession(sessionId);
sessionCreated(session);
return session;
}
};
// Register Accounting App Session Factories
((ISessionFactory) sessionFactory).registerAppFacory(ServerAccSession.class, accSessionFactory);
((ISessionFactory) sessionFactory).registerAppFacory(ClientAccSession.class, accSessionFactory);
// Register Authorization App Session Factories
((ISessionFactory) sessionFactory).registerAppFacory(ServerAuthSession.class, authSessionFactory);
((ISessionFactory) sessionFactory).registerAppFacory(ClientAuthSession.class, authSessionFactory);
}
catch (Exception e)
{
logger.error("Error Activating Diameter Base RA Entity", e);
}
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 298 for further information. <br>
* This method is called by the SLEE when a resource adaptor object instance
* is bootstrapped, either when a resource adaptor entity is created or
* during SLEE startup. The SLEE implementation will construct the resource
* adaptor object and then invoke the entityCreated method before any other
* operations can be invoked on the resource adaptor object.
*/
public void entityCreated(BootstrapContext bootstrapContext) throws ResourceException
{
logger.info("Diameter Base RA :: entityCreated :: bootstrapContext[" + bootstrapContext + "].");
this.bootstrapContext = bootstrapContext;
this.sleeEndpoint = bootstrapContext.getSleeEndpoint();
this.eventLookup = bootstrapContext.getEventLookupFacility();
this.state = ResourceAdaptorState.UNCONFIGURED;
}
/**
* implements javax.slee.resource.ResourceAdaptor The JSLEE v1.1
* Specification does not include entityDeactivated(). However, the API
* description of JSLEE v1.1 does include this method already. So, the
* documentation follows the code. <br>
* This method is called in context of project Mobicents in context of
* resource adaptor deactivation. More precisely,
* org.mobicents.slee.resource.ResourceAdaptorEntity.deactivate() calls this
* method entityDeactivated(). The method call is done AFTER the call to
* entityDeactivating(). This method signals the resource adaptor the
* transition from state "STOPPING" to state "INACTIVE".
*/
public void entityDeactivated()
{
logger.info("Diameter Base RA :: entityDeactivated.");
logger.info("Diameter Base RA :: Cleaning RA Activities.");
synchronized (this.activities)
{
activities.clear();
}
activities = null;
logger.info("Diameter Base RA :: Cleaning naming context.");
try
{
cleanNamingContext();
}
catch (NamingException e)
{
logger.error("Diameter Base RA :: Cannot unbind naming context.");
}
// Stop the stack
//try
//{
// stack.stop(5, TimeUnit.SECONDS);
//}
//catch (Exception e)
//{
// logger.error("Diameter Base RA :: Failure while stopping ");
//}
//proxy.stopService(this.bootstrapContext.getEntityName());
logger.info("Diameter Base RA :: RA Stopped.");
}
/**
* This method is called in context of project Mobicents in context of
* resource adaptor deactivation. More precisely,
* org.mobicents.slee.resource.ResourceAdaptorEntity.deactivate() calls this
* method entityDeactivating() PRIOR to invoking entityDeactivated(). This
* method signals the resource adaptor the transition from state "ACTIVE" to
* state "STOPPING".
*/
public void entityDeactivating()
{
logger.info("Diameter Base RA :: entityDeactivating.");
this.state = ResourceAdaptorState.STOPPING;
//try
//{
// Network network = stack.unwrap(Network.class);
// Iterator<ApplicationId> appIdsIt = stack.getMetaData().getLocalPeer().getCommonApplications().iterator();
//
// while(appIdsIt.hasNext())
// {
// network.removeNetworkReqListener(appIdsIt.next());
// Update the iterator (avoid ConcurrentModificationException)
// appIdsIt = stack.getMetaData().getLocalPeer().getCommonApplications().iterator();
// }
//}
//catch (InternalException e)
//{
// logger.error("", e);
//}
try{
diameterMux.unregisterListener(this);
}catch (Exception e)
{
logger.error("", e);
}
synchronized (this.activities)
{
for (ActivityHandle activityHandle : activities.keySet())
{
try
{
logger.info("Ending activity [" + activityHandle + "]");
activities.get(activityHandle).endActivity();
}
catch (Exception e)
{
logger.error("Error Deactivating Activity", e);
}
}
}
logger.info("Diameter Base RA :: entityDeactivating completed.");
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 299 for further information. <br>
* This method is called by the SLEE when a resource adaptor object instance
* is being removed, either when a resource adaptor entity is deleted or
* during SLEE shutdown. When receiving this invocation the resource adaptor
* object is expected to close any system resources it has allocated.
*/
public void entityRemoved()
{
// Stop the stack
//this.stack.destroy();
// Clean up!
this.acif = null;
this.activities = null;
this.bootstrapContext = null;
this.eventLookup = null;
this.raProvider = null;
this.sleeEndpoint = null;
this.stack = null;
logger.info("Diameter Base RA :: entityRemoved.");
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 300 for further information. <br>
* The SLEE calls this method to inform the resource adaptor object that the
* specified event was processed unsuccessfully by the SLEE. Event
* processing can fail if, for example, the SLEE doesnt have enough
* resource to process the event, a SLEE node fails during event processing
* or a system level failure prevents the SLEE from committing transactions.
*/
public void eventProcessingFailed(ActivityHandle handle, Object event, int eventID, Address address, int flags, FailureReason reason)
{
logger.info("Diameter Base RA :: eventProcessingFailed :: handle[" + handle + "], event[" + event + "], eventID[" + eventID + "], address[" + address + "], flags[" + flags +
"], reason[" + reason + "].");
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 300 for further information. <br>
* The SLEE calls this method to inform the resource adaptor object that the
* specified event was processed successfully by the SLEE. An event is
* considered to be processed successfully if the SLEE has attempted to
* deliver the event to all interested SBBs.
*/
public void eventProcessingSuccessful(ActivityHandle handle, Object event, int eventID, Address address, int flags)
{
logger.info("Diameter Base RA :: eventProcessingSuccessful :: handle[" + handle + "], event[" + event + "], eventID[" + eventID + "], address[" + address + "], flags[" +
flags + "].");
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 301 for further information. <br>
* The SLEE calls this method to get access to the underlying activity for
* an activity handle. The resource adaptor is expected to pass back a
* non-null object.
*/
public Object getActivity(ActivityHandle handle)
{
logger.info("Diameter Base RA :: getActivity :: handle[" + handle + "].");
return this.activities.get(handle);
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 301 for further information. <br>
* The SLEE calls this method to get an activity handle for an activity
* created by the underlying resource. This method is invoked by the SLEE
* when it needs to construct an activity context for an activity via an
* activity context interface factory method invoked by an SBB.
*/
public ActivityHandle getActivityHandle(Object activity)
{
logger.info("Diameter Base RA :: getActivityHandle :: activity[" + activity + "].");
if (!(activity instanceof DiameterActivity))
return null;
DiameterActivity inActivity = (DiameterActivity) activity;
for (Map.Entry<ActivityHandle, DiameterActivity> activityInfo : this.activities.entrySet())
{
Object curActivity = activityInfo.getValue();
if (curActivity.equals(inActivity))
return activityInfo.getKey();
}
return null;
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 302 for further information. <br>
* The SLEE calls this method to get reference to the Marshaler object. The
* resource adaptor implements the Marshaler interface. The Marshaler is
* used by the SLEE to convert between object and distributable forms of
* events and event handles.
*/
public Marshaler getMarshaler()
{
logger.info("Diameter Base RA :: getMarshaler");
return null;
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 302 for further information. <br>
* The SLEE calls this method to get access to the underlying resource
* adaptor interface that enables the SBB to invoke the resource adaptor, to
* send messages for example.
*/
public Object getSBBResourceAdaptorInterface(String className)
{
logger.info("Diameter Base RA :: getSBBResourceAdaptorInterface :: className[" + className + "].");
return this.raProvider;
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 301 for further information. <br>
* The SLEE calls this method to query if a specific activity belonging to
* this resource adaptor object is alive.
*/
public void queryLiveness(ActivityHandle handle)
{
logger.info("Diameter Base RA :: queryLiveness :: handle[" + handle + "].");
DiameterActivityImpl activity = (DiameterActivityImpl) activities.get(handle);
if (activity != null && !activity.isValid())
{
try
{
sleeEndpoint.activityEnding(handle);
}
catch (Exception e)
{
logger.error("", e);
}
}
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 303 for further information. <br>
* The SLEE calls this method to inform the resource adaptor that a service
* has been activated and is interested in the event types associated to the
* service key. The service must be installed with the resource adaptor via
* the serviceInstalled method before it can be activated.
*/
public void serviceActivated(String serviceKey)
{
logger.info("Diameter Base RA :: serviceActivated :: serviceKey[" + serviceKey + "].");
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 304 for further information. <br>
* The SLEE calls this method to inform the SLEE that a service has been
* deactivated and is no longer interested in the event types associated to
* the service key.
*/
public void serviceDeactivated(String serviceKey)
{
logger.info("Diameter Base RA :: serviceDeactivated :: serviceKey[" + serviceKey + "].");
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 302 for further information. <br>
* The SLEE calls this method to signify to the resource adaptor that a
* service has been installed and is interested in a specific set of events.
* The SLEE passes an event filter which identifies a set of event types
* that services in the SLEE are interested in. The SLEE calls this method
* once a service is installed.
*/
public void serviceInstalled(String serviceKey, int[] eventIDs, String[] resourceOptions)
{
logger.info("Diameter Base RA :: serviceInstalled :: serviceKey[" + serviceKey + "], eventIDs[" + eventIDs + "], resourceOptions[" + resourceOptions + "].");
}
/**
* implements javax.slee.resource.ResourceAdaptor Please refer to JSLEE v1.1
* Specification Page 303 for further information. <br>
* The SLEE calls this method to signify that a service has been
* un-installed in the SLEE. The event types associated to the service key
* are no longer of interest to a particular application.
*/
public void serviceUninstalled(String serviceKey)
{
logger.info("Diameter Base RA :: serviceUninstalled :: serviceKey[" + serviceKey + "].");
}
/**
* Set up the JNDI naming context
*/
private void initializeNamingContext() throws NamingException
{
// get the reference to the SLEE container from JNDI
SleeContainer container = SleeContainer.lookupFromJndi();
// get the entities name
String entityName = bootstrapContext.getEntityName();
ResourceAdaptorEntity resourceAdaptorEntity;
try
{
resourceAdaptorEntity = ((ResourceAdaptorEntity) container.getResourceAdaptorEntity(entityName));
}
catch (UnrecognizedResourceAdaptorEntityException uraee)
{
throw new NamingException("Failure setting up Naming Context. RA Entity not found.");
}
ResourceAdaptorTypeID raTypeId = resourceAdaptorEntity.getInstalledResourceAdaptor().getRaType().getResourceAdaptorTypeID();
// create the ActivityContextInterfaceFactory
acif = new DiameterActivityContextInterfaceFactoryImpl(resourceAdaptorEntity.getServiceContainer(), entityName);
// set the ActivityContextInterfaceFactory
resourceAdaptorEntity.getServiceContainer().getActivityContextInterfaceFactories().put(raTypeId, acif);
try
{
if (this.acif != null)
{
// parse the string = java:slee/resources/RAFrameRA/raframeacif
String jndiName = ((ResourceAdaptorActivityContextInterfaceFactory) acif).getJndiName();
int begind = jndiName.indexOf(':');
int toind = jndiName.lastIndexOf('/');
String prefix = jndiName.substring(begind + 1, toind);
String name = jndiName.substring(toind + 1);
logger.info("Diameter Base RA :: Registering in JNDI :: Prefix[" + prefix + "], Name[" + name + "].");
SleeContainer.registerWithJndi(prefix, name, this.acif);
logger.info("Diameter Base RA :: Registered in JNDI successfully.");
}
}
catch (IndexOutOfBoundsException iobe)
{
logger.info("Failure initializing name context.", iobe);
}
}
/**
* Clean the JNDI naming context
*/
private void cleanNamingContext() throws NamingException
{
try
{
if (this.acif != null)
{
// parse the string = java:slee/resources/RAFrameRA/raframeacif
String jndiName = ((ResourceAdaptorActivityContextInterfaceFactory) this.acif).getJndiName();
// remove "java:" prefix
int begind = jndiName.indexOf(':');
String javaJNDIName = jndiName.substring(begind + 1);
logger.info("Diameter Base RA :: Unregistering from JNDI :: Name[" + javaJNDIName + "].");
SleeContainer.unregisterWithJndi(javaJNDIName);
logger.info("Diameter Base RA :: Unregistered from JNDI successfully.");
}
}
catch (IndexOutOfBoundsException iobe)
{
logger.error("Failure cleaning name context.", iobe);
}
}
/**
* Initializes the RA Diameter Stack.
*
* @throws Exception
*/
private synchronized void initStack() throws Exception
{
//FIXME: Fetch stack
// Set message timeout accordingly to stack definition
// FIXME: This should come from config.. adding manually
// <ApplicationID>
// <VendorId value="193"/>
// <AuthApplId value="0"/>
// <AcctApplId value="19302"/>
// </ApplicationID>
//appIds.add(ApplicationId.createByAccAppId(193L, 19302L));
// <ApplicationID>
// <VendorId value="193"/>
// <AuthApplId value="19301"/>
// <AcctApplId value="0"/>
// </ApplicationID>
//appIds.add(ApplicationId.createByAuthAppId(193L, 19301L));
//DiameterStackMultiplexerProxyMBeanImpl proxy=new DiameterStackMultiplexerProxyMBeanImpl();
//proxy.startService(this.bootstrapContext.getEntityName());
Set<Integer> codes=events.keySet();
long[] command=new long[codes.size()];
Iterator<Integer> it=codes.iterator();
for(int i=0;i<codes.size();i++)
{
Integer ii=it.next();
command[i]=ii.longValue();
}
//this.diameterMux.registerListener( this, new ApplicationId[]{ApplicationId.createByAccAppId(193L, 19302L),ApplicationId.createByAuthAppId(193L, 19301L)});
List<ApplicationId> appIds = new ArrayList<ApplicationId>();
for(int index = 0;index<acctAppIds.length;index++)
{
appIds.add(ApplicationId.createByAccAppId(acctVendorIds[index], acctAppIds[index]));
}
for(int index = 0;index<authAppIds.length;index++)
{
appIds.add(ApplicationId.createByAuthAppId(authVendorIds[index], authAppIds[index]));
}
this.diameterMux.registerListener( this, appIds.toArray(new ApplicationId[appIds.size()]));
this.stack=this.diameterMux.getStack();
this.messageTimeout = stack.getMetaData().getConfiguration().getLongValue(MessageTimeOut.ordinal(), (Long) MessageTimeOut.defValue());
logger.info("Diameter Base RA :: Successfully initialized stack.");
}
/**
* Create the Diameter Activity Handle for an given session id
*
* @param sessionId the session identifier to create the activity handle from
* @return a DiameterActivityHandle for the provided sessionId
*/
protected DiameterActivityHandle getActivityHandle(String sessionId)
{
return new DiameterActivityHandle(sessionId);
}
/**
* Method for performing tasks when activity is created, such as informing
* SLEE about it and storing into internal map.
*
* @param ac
* the activity that has been created
*/
private void activityCreated(DiameterActivity ac)
{
try
{
// Inform SLEE that Activity Started
DiameterActivityImpl activity = (DiameterActivityImpl) ac;
sleeEndpoint.activityStarted(activity.getActivityHandle());
// Put it into our activites map
activities.put(activity.getActivityHandle(), activity);
logger.info("Activity started [" + activity.getActivityHandle() + "]");
}
catch (Exception e)
{
logger.error("Error creating activity", e);
throw new RuntimeException("Error creating activity", e);
}
}
/**
* Create Event object from request/answer
*
* @param request
* the request to create the event from, if any.
* @param answer
* the answer to create the event from, if any.
* @return a DiameterMessage object wrapping the request/answer
* @throws OperationNotSupportedException
*/
public DiameterMessage createEvent(Request request, Answer answer) throws OperationNotSupportedException
{
if (request == null && answer == null)
return null;
int commandCode = (request != null ? request.getCommandCode() : answer.getCommandCode());
if (answer != null && answer.isError()) {
return new ErrorAnswerImpl(answer);
}
switch (commandCode) {
case AbortSessionAnswer.commandCode: // ASR/ASA
return request != null ? new AbortSessionRequestImpl(request) : new AbortSessionAnswerImpl(answer);
case AccountingAnswer.commandCode: // ACR/ACA
return request != null ? new AccountingRequestImpl(request) : new AccountingAnswerImpl(answer);
case CapabilitiesExchangeAnswer.commandCode: // CER/CEA
return request != null ? new CapabilitiesExchangeRequestImpl(request) : new CapabilitiesExchangeAnswerImpl(answer);
case DeviceWatchdogAnswer.commandCode: // DWR/DWA
return request != null ? new DeviceWatchdogRequestImpl(request) : new DeviceWatchdogAnswerImpl(answer);
case DisconnectPeerAnswer.commandCode: // DPR/DPA
return request != null ? new DisconnectPeerRequestImpl(request) : new DisconnectPeerAnswerImpl(answer);
case ReAuthAnswer.commandCode: // RAR/RAA
return request != null ? new ReAuthRequestImpl(request) : new ReAuthAnswerImpl(answer);
case SessionTerminationAnswer.commandCode: // STR/STA
return request != null ? new SessionTerminationRequestImpl(request) : new SessionTerminationAnswerImpl(answer);
default:
return new ExtensionDiameterMessageImpl(request != null ? request : answer);
}
}
/**
* Method for firing event to SLEE
*
* @param handle
* the handle for the activity where event will be fired on
* @param name
* the unqualified Event name
* @param request
* the request that will be wrapped in the event, if any
* @param answer
* the answer that will be wrapped in the event, if any
*/
private void fireEvent(ActivityHandle handle, String name, Request request, Answer answer)
{
//FIXME: add even lookup cache.
try
{
int eventID = -1;
DiameterMessage event = (DiameterMessage) createEvent(request, answer);
if(event instanceof ErrorAnswer)
{
eventID = eventLookup.getEventID("net.java.slee.resource.diameter.base.events.ErrorAnswer", "java.net", "0.8");
}
else
{
eventID = eventLookup.getEventID(name, "java.net", "0.8");
}
sleeEndpoint.fireEvent(handle, event, eventID, null);
}
catch (Exception e)
{
logger.warn("Can not send event", e);
}
}
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#fireEvent(java.lang.String, java.lang.String, org.jdiameter.api.Request, org.jdiameter.api.Answer)
*/
public void fireEvent(String sessionId, String name, Request request, Answer answer)
{
this.fireEvent(getActivityHandle(sessionId), name, request, answer);
}
/**
* Method for obtaining the Peers the RA is currently conneceted to.
*
* @return an array of DiameterIdentity AVPs representing the peers.
*/
public DiameterIdentity[] getConnectedPeers()
{
if (this.stack != null)
{
try
{
// Get the list of peers from the stack
List<Peer> peers = stack.unwrap(PeerTable.class).getPeerTable();
DiameterIdentity[] result = new DiameterIdentity[peers.size()];
int i = 0;
// Get each peer from the list and make a DiameterIdentity
for (Peer peer : peers)
{
DiameterIdentity identity = new DiameterIdentity(peer.getUri().toString());
result[i++] = identity;
}
return result;
}
catch (Exception e)
{
logger.error("Failure getting peer list.", e);
}
}
return null;
}
// ##########################
// ## NETWORK REQ LISTENER ##
// ##########################
/*
* (non-Javadoc)
* @see org.jdiameter.api.NetworkReqListener#processRequest(org.jdiameter.api.Request)
*/
public Answer processRequest(Request request)
{
//String sessionId = request.getSessionId();
//DiameterActivityHandle handle = getActivityHandle(sessionId);
DiameterActivityImpl activity;
try
{
activity = (DiameterActivityImpl) raProvider.createActivity(request);
// Here we have either created activity or got old one, In cass of app activities,
// if we are here it means its initial, or something is wrong - stack is not firing
// events into correct listener?
//
// If its a base - we have to fire manually
if(activity instanceof AuthServerSessionActivityImpl)
{
AuthServerSessionActivityImpl assai = (AuthServerSessionActivityImpl)activity;
((ServerAuthSessionImpl)assai.getSession()).processRequest(request);
}
else if(activity instanceof AuthClientSessionActivityImpl)
{
AuthClientSessionActivityImpl assai=(AuthClientSessionActivityImpl)activity;
((ClientAuthSessionImpl)assai.getSession()).processRequest(request);
}
else if(activity instanceof AccountingServerSessionActivityImpl)
{
AccountingServerSessionActivityImpl assai=(AccountingServerSessionActivityImpl)activity;
((ServerAccSessionImpl)assai.getSession()).processRequest(request);
}
else if(activity instanceof AccountingClientSessionActivity)
{
AccountingClientSessionActivityImpl assai=(AccountingClientSessionActivityImpl)activity;
((ClientAccSessionImpl)assai.getSession()).processRequest(request);
}
else if(activity instanceof DiameterActivityImpl)
{
fireEvent(activity.getActivityHandle(),_ExtensionDiameterMessage, request, null);
}
else
{
//FIXME: Error?
}
}
catch (CreateActivityException e)
{
logger.error("", e);
}
// returning null so we can answer later
return null;
}
// ####################
// ## EVENT LISTENER ##
// ####################
/*
* (non-Javadoc)
*
* @see org.jdiameter.api.EventListener#receivedSuccessMessage(org.jdiameter.api.Message,
* org.jdiameter.api.Message)
*/
public void receivedSuccessMessage(Request req, Answer ans)
{
logger.info("Diameter Base RA :: receivedSuccessMessage :: " + "Request[" + req + "], Answer[" + ans + "].");
try
{
logger.info( "Received Message Result-Code: " + ans.getResultCode().getUnsigned32() );
}
catch ( AvpDataException ignore )
{
// ignore, this was just for informational purposes...
}
// FIXME: alexandre: what should we do here? end activity?
}
/*
* (non-Javadoc)
*
* @see org.jdiameter.api.EventListener#timeoutExpired(org.jdiameter.api.Message)
*/
public void timeoutExpired(Request req)
{
logger.info("Diameter Base RA :: timeoutExpired :: " + "Request[" + req + "].");
// Message delivery timed out - we have to remove activity
DiameterActivityHandle ah = new DiameterActivityHandle(req.getSessionId());
try
{
activities.get(ah).endActivity();
}
catch (Exception e)
{
logger.error("Failure processing timeout message.", e);
}
}
// #############################
// ## PROVIDER IMPLEMENTATION ##
// #############################
private class DiameterProviderImpl implements DiameterProvider {
protected final Logger logger = Logger.getLogger(DiameterProviderImpl.class);
protected DiameterBaseResourceAdaptor ra;
protected DiameterAvpFactory avpFactory = null;
protected DiameterMessageFactory messageFactory = null;
/**
* Constructor.
*
* @param ra The resource adaptor for this Provider.
*/
public DiameterProviderImpl(DiameterBaseResourceAdaptor ra)
{
this.ra = ra;
}
/*
* (non-Javadoc)
* @see net.java.slee.resource.diameter.base.DiameterProvider#createActivity()
*/
public DiameterActivity createActivity() throws CreateActivityException
{
logger.info("Diameter Base RA :: createActivity");
return this.createActivity(null, null);
}
/*
* (non-Javadoc)
* @see net.java.slee.resource.diameter.base.DiameterProvider#createActivity(net.java.slee.resource.diameter.base.events.avp.DiameterIdentity, net.java.slee.resource.diameter.base.events.avp.DiameterIdentity)
*/
public DiameterActivity createActivity(DiameterIdentity destinationHost, DiameterIdentity destinationRealm) throws CreateActivityException
{
logger.info("Diameter Base RA :: createActivity :: destinationHost[" + destinationHost + "], destinationRealm[" + destinationRealm + "]");
return createActivity(destinationHost, destinationRealm, null);
}
public DiameterActivity createActivity(DiameterIdentity destinationHost, DiameterIdentity destinationRealm, String sessionId) throws CreateActivityException
{
Session session = null;
try
{
if (sessionId != null)
{
session = proxySessionFactory.getNewSession(sessionId);
}
else
{
session = proxySessionFactory.getNewSession();
}
}
catch (InternalException e)
{
logger.error("Failure obtaining session for creating activity.", e);
return null;
}
return activities.get(getActivityHandle(session.getSessionId()));
}
// ###############################
// ## AUTHENTICATION ACTIVITIES ##
// ###############################
/*
* (non-Javadoc)
* @see net.java.slee.resource.diameter.base.DiameterProvider#createAuthenticationActivity()
*/
public AuthClientSessionActivity createAuthenticationActivity() throws CreateActivityException
{
return this.createAuthenticationActivity(null, null);
}
/*
* (non-Javadoc)
* @see net.java.slee.resource.diameter.base.DiameterProvider#createAuthenticationActivity(net.java.slee.resource.diameter.base.events.avp.DiameterIdentity, net.java.slee.resource.diameter.base.events.avp.DiameterIdentity)
*/
public AuthClientSessionActivity createAuthenticationActivity(DiameterIdentity destinationHost, DiameterIdentity destinationRealm) throws CreateActivityException
{
try
{
//we take first
ClientAuthSession session = ((ISessionFactory) stack.getSessionFactory()).getNewAppSession(null, ApplicationId.createByAuthAppId(authVendorIds[0], authAppIds[0]), ClientAuthSession.class);
return (AuthClientSessionActivity) activities.get(getActivityHandle(session.getSessions().get(0).getSessionId()));
}
catch (InternalException e) {
throw new CreateActivityException("Internal exception while creating Authentication Activity", e);
}
catch (IllegalDiameterStateException e) {
throw new CreateActivityException("Illegal Diameter State exception while creating Authentication Activity", e);
}
}
public AuthServerSessionActivity createAuthenticationServerActivity(Request request) throws CreateActivityException
{
ServerAuthSession session = null;
try
{
//we take first
session = ((ISessionFactory) stack.getSessionFactory()).getNewAppSession(null, ApplicationId.createByAuthAppId(authVendorIds[0], authAppIds[0]), ServerAuthSession.class, new Object[]{request});
return (AuthServerSessionActivity) activities.get(getActivityHandle(session.getSessions().get(0).getSessionId()));
}
catch (InternalException e) {
throw new CreateActivityException("Internal exception while creating Server Authentication Activity", e);
}
catch (IllegalDiameterStateException e) {
throw new CreateActivityException("Illegal Diameter State exception while creating Server Authentication Activity", e);
}
}
// ###########################
// ## ACCOUNTING ACTIVITIES ##
// ###########################
/*
* (non-Javadoc)
* @see net.java.slee.resource.diameter.base.DiameterProvider#createAccountingActivity()
*/
public AccountingClientSessionActivity createAccountingActivity() throws CreateActivityException
{
return this.createAccountingActivity(null, null);
}
/*
* (non-Javadoc)
* @see net.java.slee.resource.diameter.base.DiameterProvider#createAccountingActivity(net.java.slee.resource.diameter.base.events.avp.DiameterIdentity, net.java.slee.resource.diameter.base.events.avp.DiameterIdentity)
*/
public AccountingClientSessionActivity createAccountingActivity(DiameterIdentity destinationHost, DiameterIdentity destinationRealm) throws CreateActivityException
{
try
{
// FIXME: alexandre: This must be fixed, we need way to get Application-Id!
ClientAccSession session = ((ISessionFactory) stack.getSessionFactory()).getNewAppSession(null, ApplicationId.createByAccAppId(acctVendorIds[0], acctAppIds[0]), ClientAccSession.class);
return (AccountingClientSessionActivity) activities.get(getActivityHandle(session.getSessions().get(0).getSessionId()));
}
catch (InternalException e) {
throw new CreateActivityException("Internal exception while creating Client Accounting Activity", e);
}
catch (IllegalDiameterStateException e) {
throw new CreateActivityException("Illegal Diameter State exception while creating Client Accounting Activity", e);
}
}
public AccountingServerSessionActivity createAccountingServerActivity(Request req) throws CreateActivityException
{
ServerAccSession session = null;
try
{
ApplicationId appId = req.getApplicationIdAvps().isEmpty() ? null : req.getApplicationIdAvps().iterator().next();
session = ((ISessionFactory) stack.getSessionFactory()).getNewAppSession(req.getSessionId(), appId, ServerAccSession.class, req);
if (session == null)
{
throw new CreateActivityException("Got NULL Session while creating Server Accounting Activity");
}
}
catch (InternalException e) {
throw new CreateActivityException("Internal exception while creating Server Accounting Activity", e);
}
catch (IllegalDiameterStateException e) {
throw new CreateActivityException("Illegal Diameter State exception while creating Server Accounting Activity", e);
}
return (AccountingServerSessionActivity) activities.get(getActivityHandle(session.getSessions().get(0).getSessionId()));
}
/**
* This method is for internal use only, it creates activities for
* requests that do not fall in certain app range or no activitis were
* found <br>
* It should distinguish between initial requests, requests with
* diferent domains etc. - respo for createing XXXServerSession or basic
* diameter activity lies in this method
*
* @param message
* @return
*/
DiameterActivity createActivity(Message message) throws CreateActivityException
{
String sessionId = message.getSessionId();
DiameterActivityHandle handle = new DiameterActivityHandle(sessionId);
if (activities.keySet().contains(handle))
{
return activities.get(handle);
}
else
{
DiameterIdentity destinationHost = null;
DiameterIdentity destinationRealm = null;
AvpSet avps = message.getAvps();
Avp raw = null;
if((raw = avps.getAvp(Avp.DESTINATION_HOST)) != null)
{
try
{
destinationHost = new DiameterIdentity(raw.getDiameterIdentity());
}
catch (AvpDataException e)
{
logger.error("", e);
}
}
if((raw = avps.getAvp(Avp.DESTINATION_REALM)) != null)
{
try
{
destinationRealm = new DiameterIdentity(raw.getDiameterIdentity());
}
catch (AvpDataException e)
{
logger.error("", e);
}
}
if (isMessageOfType(message, DiameterAvpCodes.AUTH_APPLICATION_ID))
{
return createAuthenticationServerActivity((Request) message);
}
else if (isMessageOfType(message, DiameterAvpCodes.ACCT_APPLICATION_ID))
{
return createAccountingServerActivity((Request) message);
}
else // Base Activity
{
return this.createActivity(destinationHost, destinationRealm, message.getSessionId());
}
}
}
private boolean isMessageOfType(Message message, int type)
{
try
{
Avp vendorSpecificAvp = null;
if( message.getAvps().getAvp(type) != null )
{
return true;
}
else if( (vendorSpecificAvp = message.getAvps().getAvp(DiameterAvpCodes.VENDOR_SPECIFIC_APPLICATION_ID)) != null )
{
return vendorSpecificAvp.getGrouped().getAvp(type) != null;
}
}
catch (Exception ignore) {
// ignore this... say it isn't
}
return false;
}
public DiameterMessageFactory getDiameterMessageFactory()
{
if (this.messageFactory == null)
{
this.messageFactory = new DiameterMessageFactoryImpl(this.ra.stack);
}
return this.messageFactory;
}
public DiameterAvpFactory getDiameterAvpFactory()
{
if (this.avpFactory == null)
{
this.avpFactory = new DiameterAvpFactoryImpl();
}
return this.avpFactory;
}
public DiameterMessage sendSyncRequest(DiameterMessage message) throws IOException
{
try
{
if (message instanceof DiameterMessageImpl)
{
DiameterMessageImpl msg = (DiameterMessageImpl) message;
// FIXME: baranowb - get session from RA! THIS WILL BE COMPLICATED IN CASE WE HAVE RELLY AGENT!
// here we can have leaks ;[
String sessionId = message.getSessionId();
DiameterActivityHandle handle = new DiameterActivityHandle(sessionId);
if (!activities.keySet().contains(handle))
{
createActivity(msg.getGenericData());
}
DiameterActivityImpl activity = (DiameterActivityImpl) getActivity(handle);
return activity.sendSyncMessage(message);
}
} catch (JAvpNotAllowedException e) {
AvpNotAllowedException anae = new AvpNotAllowedException("Message validation failed.", e, e.getAvpCode(), e.getVendorId());
throw anae;
} catch (Exception e) {
e.printStackTrace();
IOException ioe = new IOException("Failed to send message, due to: " + e);
throw ioe;
}
// FIXME Throw unknown message exception?
return null;
}
public DiameterIdentity[] getConnectedPeers() {
return this.ra.getConnectedPeers();
}
public int getPeerCount() {
return getConnectedPeers().length;
}
}
// #############################
// ## BASE SESSION MANAGEMENT ##
// #############################
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#sessionCreated(org.jdiameter.api.acc.ServerAccSession)
*/
public void sessionCreated(ServerAccSession session)
{
DiameterMessageFactoryImpl msgFactory = new DiameterMessageFactoryImpl(stack);
AccountingServerSessionActivityImpl activity = new AccountingServerSessionActivityImpl(msgFactory, diameterAvpFactory, session, messageTimeout,
null, null, sleeEndpoint, stack);
session.addStateChangeNotification(activity);
activity.setSessionListener(this);
activityCreated(activity);
}
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#sessionCreated(org.jdiameter.api.auth.ServerAuthSession)
*/
public void sessionCreated(ServerAuthSession session)
{
DiameterMessageFactoryImpl msgFactory = new DiameterMessageFactoryImpl(session.getSessions().get(0), stack, null, null);
AuthServerSessionActivityImpl activity = new AuthServerSessionActivityImpl(msgFactory, diameterAvpFactory, session, messageTimeout,
null, null, sleeEndpoint);
session.addStateChangeNotification(activity);
activity.setSessionListener(this);
activityCreated(activity);
}
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#sessionCreated(org.jdiameter.api.auth.ClientAuthSession)
*/
public void sessionCreated(ClientAuthSession session)
{
DiameterMessageFactoryImpl msgFactory = new DiameterMessageFactoryImpl(session.getSessions().get(0), stack, null, null);
AuthClientSessionActivityImpl activity = new AuthClientSessionActivityImpl(msgFactory, diameterAvpFactory, session, messageTimeout,
null, null, sleeEndpoint);
session.addStateChangeNotification(activity);
activity.setSessionListener(this);
activityCreated(activity);
}
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#sessionCreated(org.jdiameter.api.acc.ClientAccSession)
*/
public void sessionCreated(ClientAccSession session)
{
DiameterMessageFactoryImpl msgFactory = new DiameterMessageFactoryImpl(stack);
AccountingClientSessionActivityImpl activity = new AccountingClientSessionActivityImpl(msgFactory, diameterAvpFactory, session, messageTimeout,
null, null, sleeEndpoint);
activity.setSessionListener(this);
session.addStateChangeNotification(activity);
activityCreated(activity);
}
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#sessionCreated(org.jdiameter.api.Session)
*/
public void sessionCreated(Session session)
{
DiameterMessageFactoryImpl msgFactory = new DiameterMessageFactoryImpl(session, stack, null, null);
DiameterActivityImpl activity = new DiameterActivityImpl(msgFactory, diameterAvpFactory, session, this, messageTimeout, null, null, sleeEndpoint);
//FIXME: baranowb: add basic session mgmt for base? or do we relly on responses?
//session.addStateChangeNotification(activity);
activity.setSessionListener(this);
activityCreated(activity);
}
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#sessionDestroyed(java.lang.String, java.lang.Object)
*/
public void sessionDestroyed(String sessionId, Object appSession)
{
try
{
this.sleeEndpoint.activityEnding(getActivityHandle(sessionId));
}
catch (Exception e) {
logger.error( "Failure Ending Activity with Session-Id[" + sessionId + "]", e );
}
}
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#sessionExists(java.lang.String)
*/
public boolean sessionExists(String sessionId)
{
return this.activities.containsKey(getActivityHandle(sessionId));
}
/*
* (non-Javadoc)
* @see org.mobicents.slee.resource.diameter.base.handlers.BaseSessionCreationListener#getSupportedApplications()
*/
public ApplicationId[] getSupportedApplications() {
List<ApplicationId> appIds = new ArrayList<ApplicationId>();
for (int index = 0; index < acctAppIds.length; index++) {
appIds.add(ApplicationId.createByAccAppId(acctVendorIds[index], acctAppIds[index]));
}
for (int index = 0; index < authAppIds.length; index++) {
appIds.add(ApplicationId.createByAuthAppId(authVendorIds[index], authAppIds[index]));
}
return appIds.toArray(new ApplicationId[appIds.size()]);
}
private long[] acctVendorIds;
private long[] authVendorIds;
private long[] acctAppIds;
private long[] authAppIds;
public String getAcctVendorIds() {
return convertToString(acctVendorIds);
}
public void setAcctVendorIds(String vendorIds) {
this.acctVendorIds = convertToLong(vendorIds);
}
public String getAuthVendorIds() {
return convertToString(authVendorIds);
}
public void setAuthVendorIds(String vendorIds) {
this.authVendorIds = convertToLong(vendorIds);
}
public String getAcctAppIds() {
return convertToString(acctAppIds);
}
public void setAcctAppIds(String acctAppId) {
this.acctAppIds = convertToLong(acctAppId);
}
public String getAuthAppIds() {
return convertToString(authAppIds);
}
public void setAuthAppIds(String authAppId) {
this.authAppIds = convertToLong(authAppId);
}
protected String convertToString(long[] l) {
String s = "";
for (int index = 0; index < l.length; index++) {
s += l[index];
if (l.length - 1 != index) {
s += ",";
}
}
return s;
}
protected long[] convertToLong(String s) {
String[] ss = s.split(",");
long[] l = new long[ss.length];
for (int index = 0; index < ss.length; index++) {
l[index] = Long.valueOf(ss[index]);
}
return l;
}
}