package org.mobicents.slee.resource.diameter.cca.handlers;
import java.util.concurrent.ScheduledFuture;
import org.apache.log4j.Logger;
import org.jdiameter.api.Answer;
import org.jdiameter.api.ApplicationId;
import org.jdiameter.api.InternalException;
import org.jdiameter.api.Message;
import org.jdiameter.api.Request;
import org.jdiameter.api.SessionFactory;
import org.jdiameter.api.acc.events.AccountAnswer;
import org.jdiameter.api.acc.events.AccountRequest;
import org.jdiameter.api.app.AppAnswerEvent;
import org.jdiameter.api.app.AppEvent;
import org.jdiameter.api.app.AppRequestEvent;
import org.jdiameter.api.app.AppSession;
import org.jdiameter.api.app.StateChangeListener;
import org.jdiameter.api.auth.events.AbortSessionAnswer;
import org.jdiameter.api.auth.events.AbortSessionRequest;
import org.jdiameter.api.auth.events.ReAuthAnswer;
import org.jdiameter.api.auth.events.ReAuthRequest;
import org.jdiameter.api.auth.events.SessionTermAnswer;
import org.jdiameter.api.auth.events.SessionTermRequest;
import org.jdiameter.api.cca.ClientCCASession;
import org.jdiameter.api.cca.ClientCCASessionListener;
import org.jdiameter.api.cca.ServerCCASession;
import org.jdiameter.api.cca.ServerCCASessionListener;
import org.jdiameter.api.cca.events.JCreditControlAnswer;
import org.jdiameter.api.cca.events.JCreditControlRequest;
import org.jdiameter.client.impl.app.cca.ClientCCASessionImpl;
import org.jdiameter.common.api.app.IAppSessionFactory;
import org.jdiameter.common.api.app.cca.ICCAMessageFactory;
import org.jdiameter.common.api.app.cca.IClientCCASessionContext;
import org.jdiameter.common.api.app.cca.IServerCCASessionContext;
import org.jdiameter.common.impl.app.auth.ReAuthAnswerImpl;
import org.jdiameter.common.impl.app.auth.ReAuthRequestImpl;
import org.jdiameter.common.impl.app.cca.JCreditControlAnswerImpl;
import org.jdiameter.common.impl.app.cca.JCreditControlRequestImpl;
import org.jdiameter.server.impl.app.cca.ServerCCASessionImpl;
import org.mobicents.slee.resource.diameter.base.DiameterActivityHandle;
import org.mobicents.slee.resource.diameter.cca.CCAResourceAdaptor;
import static org.mobicents.slee.resource.diameter.cca.handlers.CCASessionCreationListener.*;
/**
*
* CreditControlSessionFactory.java
*
* <br>
* Super project: mobicents <br>
* 3:19:55 AM Dec 30, 2008 <br>
*
* @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
* @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
*/
public class CreditControlSessionFactory implements IAppSessionFactory, ClientCCASessionListener, ServerCCASessionListener, StateChangeListener, ICCAMessageFactory, IServerCCASessionContext,
IClientCCASessionContext {
protected SessionFactory sessionFactory = null;
protected CCASessionCreationListener resourceAdaptor = null;
// Message timeout value (in milliseconds)
protected long messageTimeout = 5000;
protected int defaultDirectDebitingFailureHandling = 0;
protected int defaultCreditControlFailureHandling = 0;
// its seconds
protected long defaultValidityTime = 30;
protected long defaultTxTimerValue = 10;
protected Logger logger = Logger.getLogger(CreditControlSessionFactory.class);
public CreditControlSessionFactory(SessionFactory sessionFactory, CCASessionCreationListener resourceAdaptor, long messageTimeout) {
super();
this.sessionFactory = sessionFactory;
this.resourceAdaptor = resourceAdaptor;
this.messageTimeout = messageTimeout;
}
public CreditControlSessionFactory(SessionFactory sessionFactory, CCASessionCreationListener resourceAdaptor, long messageTimeout, int defaultDirectDebitingFailureHandling,
int defaultCreditControlFailureHandling, long defaultValidityTime, long defaultTxTimerValue) {
super();
this.sessionFactory = sessionFactory;
this.resourceAdaptor = resourceAdaptor;
this.messageTimeout = messageTimeout;
this.defaultDirectDebitingFailureHandling = defaultDirectDebitingFailureHandling;
this.defaultCreditControlFailureHandling = defaultCreditControlFailureHandling;
this.defaultValidityTime = defaultValidityTime;
this.defaultTxTimerValue = defaultTxTimerValue;
}
public AppSession getNewSession(String sessionId, Class<? extends AppSession> aClass, ApplicationId applicationId, Object[] args) {
AppSession appSession = null;
try {
if (aClass == ClientCCASession.class) {
ClientCCASessionImpl clientSession = null;
if (args != null && args.length > 0 && args[0] instanceof Request) {
Request request = (Request) args[0];
clientSession = new ClientCCASessionImpl(request.getSessionId(), this, sessionFactory, this);
} else {
clientSession = new ClientCCASessionImpl(sessionId, this, sessionFactory, this);
}
clientSession.getSessions().get(0).setRequestListener(clientSession);
clientSession.addStateChangeNotification(this);
this.resourceAdaptor.sessionCreated(clientSession);
appSession = clientSession;
} else if (aClass == ServerCCASession.class) {
ServerCCASessionImpl serverSession = null;
if (args != null && args.length > 0 && args[0] instanceof Request) {
// This shouldnt happen but just in case
Request request = (Request) args[0];
serverSession = new ServerCCASessionImpl(request.getSessionId(), this, sessionFactory, this);
} else {
serverSession = new ServerCCASessionImpl(sessionId, this, sessionFactory, this);
}
serverSession.addStateChangeNotification(this);
serverSession.getSessions().get(0).setRequestListener(serverSession);
this.resourceAdaptor.sessionCreated(serverSession);
appSession = serverSession;
} else {
throw new IllegalArgumentException("Wrong session class!![" + aClass + "]. Supported[" + ClientCCASession.class + "," + ServerCCASession.class + "]");
}
} catch (Exception e) {
logger.error("Failure to obtain new Credit-Control Session.", e);
}
return appSession;
}
// ////////////////////
// Message Handlers //
// ////////////////////
private void doMessage(String name, AppSession appSession, AppEvent message, boolean isRequest) throws InternalException {
DiameterActivityHandle handle = new DiameterActivityHandle(appSession.getSessions().get(0).getSessionId());
if (isRequest) {
this.resourceAdaptor.fireEvent(handle, name, (Request) message.getMessage(), null);
} else {
this.resourceAdaptor.fireEvent(handle, name, null, (Answer) message.getMessage());
}
}
public void doCreditControlRequest(ServerCCASession session, JCreditControlRequest request) throws InternalException {
doMessage(_CreditControlRequest, session, request, true);
}
public void doCreditControlAnswer(ClientCCASession session, JCreditControlRequest request, JCreditControlAnswer answer) throws InternalException {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_CreditControlAnswer, session, answer, false);
}
public void doReAuthRequest(ClientCCASession session, ReAuthRequest request) throws InternalException {
doMessage(_ReAuthRequest, session, request, true);
}
public void doReAuthAnswer(ServerCCASession session, ReAuthRequest request, ReAuthAnswer answer) throws InternalException {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_ReAuthAnswer, session, answer, false);
}
public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException {
// baranowb: here we get something weird, lets do extension
// Still we relly on CCA termination mechanisms, those message are sent
// via generic send, which does not trigger FSM
DiameterActivityHandle handle = new DiameterActivityHandle(session.getSessions().get(0).getSessionId());
logger.info("Diameter CCA RA :: doOtherEvent :: appSession[" + session + "], Request[" + request + "], Answer[" + answer + "]");
if (answer != null) {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_ExtensionDiameterMessage, session, answer, false);
} else {
doMessage(_ExtensionDiameterMessage, session, answer, true);
}
}
// /////////////////////////
// Base Message Handlers //
// /////////////////////////
public void doAbortSessionRequest(ClientCCASession session, AbortSessionRequest request) throws InternalException {
doMessage(_AbortSessionRequest, session, request, true);
}
public void doAbortSessionAnswer(ClientCCASession session, AbortSessionRequest request, AbortSessionAnswer answer) throws InternalException {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_AbortSessionAnswer,session, answer, false);
}
public void doAccountingRequest(ClientCCASession session, AccountRequest request) throws InternalException {
doMessage(_AccountingRequest,session, request, true);
}
public void doAccountingAnswer(ClientCCASession session, AccountRequest request, AccountAnswer answer) throws InternalException {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_AccountingAnswer,session, answer, false);
}
public void doSessionTerminationRequest(ClientCCASession session, SessionTermRequest request) throws InternalException {
doMessage(_SessionTerminationRequest,session, request, true);
}
public void doSessionTerminationAnswer(ClientCCASession session, SessionTermRequest request, SessionTermAnswer answer) throws InternalException {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_SessionTerminationAnswer,session, answer, false);
}
public void doAbortSessionRequest(ServerCCASession session, AbortSessionRequest request) throws InternalException {
doMessage(_AbortSessionRequest,session, request, true);
}
public void doAbortSessionAnswer(ServerCCASession session, AbortSessionRequest request, AbortSessionAnswer answer) throws InternalException {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_AbortSessionAnswer,session, answer, false);
}
public void doAccountingRequest(ServerCCASession session, AccountRequest request) throws InternalException {
doMessage(_AccountingRequest,session, request, true);
}
public void doAccountingAnswer(ServerCCASession session, AccountRequest request, AccountAnswer answer) throws InternalException {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_AccountingAnswer,session, answer, false);
}
public void doSessionTerminationRequest(ServerCCASession session, SessionTermRequest request) throws InternalException {
doMessage(_SessionTerminationRequest,session, request, true);
}
public void doSessionTerminationAnswer(ServerCCASession session, SessionTermRequest request, SessionTermAnswer answer) throws InternalException {
if (answer.getMessage().isError())
doMessage(_ErrorAnswer, session, answer, false);
else
doMessage(_SessionTerminationAnswer,session, answer, false);
}
// ///////////////////////////
// Message Factory Methods //
// ///////////////////////////
public JCreditControlAnswer createCreditControlAnswer(Answer answer) {
return new JCreditControlAnswerImpl(answer);
}
public JCreditControlRequest createCreditControlRequest(Request req) {
return new JCreditControlRequestImpl(req);
}
public ReAuthAnswer createReAuthAnswer(Answer answer) {
return new ReAuthAnswerImpl(answer);
}
public ReAuthRequest createReAuthRequest(Request req) {
return new ReAuthRequestImpl(req);
}
// ///////////////////
// Context Methods //
// ///////////////////
public void stateChanged(Enum oldState, Enum newState) {
if (logger.isInfoEnabled()) {
logger.info("Diameter CCA SessionFactory :: stateChanged :: oldState[" + oldState + "], newState[" + newState + "]");
}
}
public void sessionSupervisionTimerExpired(ServerCCASession session) {
//this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session);
session.release();
}
public void sessionSupervisionTimerReStarted(ServerCCASession session, ScheduledFuture future) {
// TODO Complete this method.
}
public void sessionSupervisionTimerStarted(ServerCCASession session, ScheduledFuture future) {
// TODO Complete this method.
}
public void sessionSupervisionTimerStopped(ServerCCASession session, ScheduledFuture future) {
// TODO Complete this method.
}
public void timeoutExpired(Request request) {
// FIXME What should we do when there's a timeout?
}
public void denyAccessOnDeliverFailure(ClientCCASession clientCCASessionImpl, Message request) {
// TODO Complete this method.
}
public void denyAccessOnFailureMessage(ClientCCASession clientCCASessionImpl) {
// TODO Complete this method.
}
public void denyAccessOnTxExpire(ClientCCASession clientCCASessionImpl) {
//this.resourceAdaptor.sessionDestroyed(clientCCASessionImpl.getSessions().get(0).getSessionId(), clientCCASessionImpl);
clientCCASessionImpl.release();
}
public int getDefaultCCFHValue() {
return defaultCreditControlFailureHandling;
}
public int getDefaultDDFHValue() {
return defaultDirectDebitingFailureHandling;
}
public long getDefaultTxTimerValue() {
return defaultTxTimerValue;
}
public void grantAccessOnDeliverFailure(ClientCCASession clientCCASessionImpl, Message request) {
// TODO Auto-generated method stub
}
public void grantAccessOnFailureMessage(ClientCCASession clientCCASessionImpl) {
// TODO Auto-generated method stub
}
public void grantAccessOnTxExpire(ClientCCASession clientCCASessionImpl) {
// TODO Auto-generated method stub
}
public void indicateServiceError(ClientCCASession clientCCASessionImpl) {
// TODO Auto-generated method stub
}
public void txTimerExpired(ClientCCASession session) {
//this.resourceAdaptor.sessionDestroyed(session.getSessions().get(0).getSessionId(), session);
session.release();
}
public long[] getApplicationIds() {
// FIXME: What should we do here?
return new long[] { 4 };
}
public long getDefaultValidityTime() {
return this.defaultValidityTime;
}
}