package org.mobicents.slee.resource.diameter.base;
import java.io.IOException;
import javax.slee.resource.SleeEndpoint;
import net.java.slee.resource.diameter.base.AccountingServerSessionActivity;
import net.java.slee.resource.diameter.base.AccountingSessionState;
import net.java.slee.resource.diameter.base.events.AccountingAnswer;
import net.java.slee.resource.diameter.base.events.AccountingRequest;
import net.java.slee.resource.diameter.base.events.avp.AvpNotAllowedException;
import net.java.slee.resource.diameter.base.events.avp.DiameterAvp;
import net.java.slee.resource.diameter.base.events.avp.DiameterIdentity;
import org.jdiameter.api.Answer;
import org.jdiameter.api.Avp;
import org.jdiameter.api.EventListener;
import org.jdiameter.api.Message;
import org.jdiameter.api.Request;
import org.jdiameter.api.Stack;
import org.jdiameter.api.acc.ServerAccSession;
import org.jdiameter.common.api.app.acc.ServerAccSessionState;
import org.jdiameter.common.impl.app.acc.AccountAnswerImpl;
import org.jdiameter.common.impl.app.acc.AccountRequestImpl;
import org.jdiameter.common.impl.validation.JAvpNotAllowedException;
import org.mobicents.slee.resource.diameter.base.events.AccountingAnswerImpl;
import org.mobicents.slee.resource.diameter.base.events.DiameterMessageImpl;
/**
*
* AccountingServerSessionActivityImpl.java
*
* @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
* @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
*/
public class AccountingServerSessionActivityImpl extends AccountingSessionActivityImpl implements AccountingServerSessionActivity {
protected ServerAccSession serverSession = null;
// These are default values, should be overriden by stack.
protected String originHost = "aaa://127.0.0.1:3868";
protected String originRealm = "mobicents.org";
boolean destroyAfterSending = false;
public AccountingServerSessionActivityImpl(DiameterMessageFactoryImpl messageFactory, DiameterAvpFactoryImpl avpFactory, ServerAccSession serverSession, long timeout,
DiameterIdentity destinationHost, DiameterIdentity destinationRealm, SleeEndpoint endpoint, Stack stack) {
super(messageFactory, avpFactory, null, (EventListener<Request, Answer>) serverSession, timeout, destinationHost, destinationRealm, endpoint);
this.serverSession = serverSession;
// this.serverSession.addStateChangeNotification(this);
super.setCurrentWorkingSession(this.serverSession.getSessions().get(0));
this.state = AccountingSessionState.Idle;
this.originHost = stack.getMetaData().getLocalPeer().getUri().toString();
this.originRealm = stack.getMetaData().getLocalPeer().getRealmName();
}
public AccountingAnswer createAccountAnswer(AccountingRequest request) {
try {
// Get the impl
DiameterMessageImpl implRequest = (DiameterMessageImpl) request;
// Get raw message from impl
Message rawMessage = implRequest.getGenericData();
// Extract interesting AVPs
DiameterAvp accRecordNumber = avpFactory.createAvp(Avp.ACC_RECORD_NUMBER, rawMessage.getAvps().getAvp(Avp.ACC_RECORD_NUMBER).getRaw());
DiameterAvp accRecordType = avpFactory.createAvp(Avp.ACC_RECORD_TYPE, rawMessage.getAvps().getAvp(Avp.ACC_RECORD_TYPE).getRaw());
DiameterAvp originHost = avpFactory.createAvp(Avp.ORIGIN_HOST, this.originHost.getBytes());
DiameterAvp originRealm = avpFactory.createAvp(Avp.ORIGIN_REALM, this.originRealm.getBytes());
DiameterAvp sessionId = avpFactory.createAvp(Avp.SESSION_ID, serverSession.getSessions().get(0).getSessionId());
DiameterMessageImpl answer = (DiameterMessageImpl) messageFactory.createMessage(implRequest.getHeader(), new DiameterAvp[] { accRecordNumber, accRecordType, originHost, originRealm,
sessionId });
// RFC3588, Page 119-120
// One of Acct-Application-Id and Vendor-Specific-Application-Id AVPs
// MUST be present. If the Vendor-Specific-Application-Id grouped AVP
// is present, it must have an Acct-Application-Id inside.
if (request.hasAcctApplicationId()) {
answer.addAvp(avpFactory.createAvp(Avp.ACCT_APPLICATION_ID, request.getAcctApplicationId()));
} else {
// We should have an Vendor-Specific-Application-Id grouped AVP
answer.addAvp(request.getVendorSpecificApplicationId());
}
// Get the raw Answer
Message rawAnswer = answer.getGenericData();
// This is an answer.
rawAnswer.setRequest(false);
return new AccountingAnswerImpl(rawAnswer);
} catch (Exception e) {
logger.error("", e);
}
return null;
}
public AccountingAnswer createAccountAnswer(AccountingRequest request, int resultCode) {
AccountingAnswer answer = this.createAccountAnswer(request);
answer.setResultCode(resultCode);
return answer;
}
public void sendAccountAnswer(AccountingAnswer answer) throws IOException {
// FIXME: baranowb - add setting of proper session
// super.sendMessage(answer);
// try
// {
// AccountingAnswerImpl aca = (AccountingAnswerImpl)answer;
//
// this.serverSession.getSessions().get(0).send( aca.getGenericData() );
//
// if( destroyAfterSending )
// {
// String sessionId =
// this.serverSession.getSessions().get(0).getSessionId();
// this.serverSession.release();
// this.baseListener.sessionDestroyed(sessionId, this.serverSession);
// }
// }
// catch ( Exception e )
// {
// logger.error( "Failure sending Account-Answer.", e );
// }
try {
AccountingAnswerImpl aca = (AccountingAnswerImpl) answer;
this.serverSession.sendAccountAnswer(new AccountAnswerImpl((Answer) aca.getGenericData()));
// FIXME: check this?
if (destroyAfterSending) {
String sessionId = this.serverSession.getSessions().get(0).getSessionId();
this.serverSession.release();
this.baseListener.sessionDestroyed(sessionId, this.serverSession);
}
} 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;
}
}
public ServerAccSession getSession() {
return this.serverSession;
}
public void stateChanged(Enum oldState, Enum newState) {
if (newState == ServerAccSessionState.IDLE) {
super.state = AccountingSessionState.Idle;
destroyAfterSending = true;
} else {
super.state = AccountingSessionState.Open;
}
}
}