package org.mobicents.slee.examples.diameter.cca;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.slee.ActivityContextInterface;
import javax.slee.RolledBackContext;
import javax.slee.SbbContext;
import javax.slee.facilities.TimerEvent;
import javax.slee.facilities.TimerFacility;
import javax.slee.facilities.TimerOptions;
import javax.slee.serviceactivity.ServiceActivity;
import javax.slee.serviceactivity.ServiceActivityFactory;
import net.java.slee.resource.diameter.base.events.avp.DiameterAvp;
import net.java.slee.resource.diameter.base.events.avp.DiameterIdentity;
import net.java.slee.resource.diameter.cca.CreditControlAVPFactory;
import net.java.slee.resource.diameter.cca.CreditControlActivityContextInterfaceFactory;
import net.java.slee.resource.diameter.cca.CreditControlClientSession;
import net.java.slee.resource.diameter.cca.CreditControlMessageFactory;
import net.java.slee.resource.diameter.cca.CreditControlProvider;
import net.java.slee.resource.diameter.cca.CreditControlServerSession;
import net.java.slee.resource.diameter.cca.events.CreditControlAnswer;
import net.java.slee.resource.diameter.cca.events.CreditControlRequest;
import net.java.slee.resource.diameter.cca.events.avp.CcMoneyAvp;
import net.java.slee.resource.diameter.cca.events.avp.CreditControlAVPCodes;
import net.java.slee.resource.diameter.cca.events.avp.RequestedServiceUnitAvp;
import org.apache.log4j.Logger;
import org.jdiameter.api.Avp;
/**
* Start time:21:45:41 2008-12-14<br>
* Project: mobicents-diameter-parent<br>
*
* @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
* @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
*/
public abstract class CCAExampleSBB implements javax.slee.Sbb {
private static Logger logger = Logger.getLogger(CCAExampleSBB.class);
private SbbContext sbbContext = null; // This SBB's context
private Context myEnv = null; // This SBB's environment
private CreditControlActivityContextInterfaceFactory acif = null;
private CreditControlProvider provider = null;
private CreditControlMessageFactory messageFactory = null;
private CreditControlAVPFactory avpFactory = null;
private TimerFacility timerFacility = null;
private String originIP = "127.0.0.1";
private String originPort = "1812";
private String originRealm = "mobicents.org";
private String destinationIP = "127.0.0.1";
private String destinationPort = "3868";
private String destinationRealm = "mobicents.org";
private boolean actAsServer = false;
// protected boolean isEventBased = true;
// protected boolean sentInitialAnswer = false;
// protected boolean sentUpdateAnswer = false;
// protected boolean sentTerminationAnswer = false;
public void setSbbContext(SbbContext context) {
logger.info("sbbRolledBack invoked.");
this.sbbContext = context;
try {
myEnv = (Context) new InitialContext().lookup("java:comp/env");
provider = (CreditControlProvider) myEnv.lookup("slee/resources/diameter-cca-ra-interface");
logger.info("Got Provider:" + provider);
messageFactory = provider.getCreditControlMessageFactory();
logger.info("Got Message Factory:" + messageFactory);
avpFactory = provider.getCreditControlAVPFactory();
logger.info("Got AVP Factory:" + avpFactory);
acif = (CreditControlActivityContextInterfaceFactory) myEnv.lookup("slee/resources/CCAResourceAdaptor/java.net/0.8.1/acif");
// Get the timer facility
timerFacility = (TimerFacility) myEnv.lookup("slee/facilities/timer");
} catch (Exception e) {
logger.error("Unable to set sbb context.", e);
}
}
public void unsetSbbContext() {
if (logger.isInfoEnabled())
logger.info("unsetSbbContext invoked.");
this.sbbContext = null;
}
public void sbbCreate() throws javax.slee.CreateException {
if (logger.isInfoEnabled())
logger.info("sbbCreate invoked.");
}
public void sbbPostCreate() throws javax.slee.CreateException {
if (logger.isInfoEnabled())
logger.info("sbbPostCreate invoked.");
}
public void sbbActivate() {
if (logger.isInfoEnabled())
logger.info("sbbActivate invoked.");
}
public void sbbPassivate() {
if (logger.isInfoEnabled())
logger.info("sbbPassivate invoked.");
}
public void sbbRemove() {
if (logger.isInfoEnabled())
logger.info("sbbRemove invoked.");
}
public void sbbLoad() {
if (logger.isInfoEnabled())
logger.info("sbbLoad invoked.");
}
public void sbbStore() {
if (logger.isInfoEnabled())
logger.info("sbbStore invoked.");
}
public void sbbExceptionThrown(Exception exception, Object event, ActivityContextInterface activity) {
if (logger.isInfoEnabled())
logger.info("sbbRolledBack invoked.");
}
public void sbbRolledBack(RolledBackContext context) {
if (logger.isInfoEnabled())
logger.info("sbbRolledBack invoked.");
}
protected SbbContext getSbbContext() {
if (logger.isInfoEnabled())
logger.info("getSbbContext invoked.");
return sbbContext;
}
// ##########################################################################
// ## EVENT HANDLERS ##
// ##########################################################################
public void onServiceStartedEvent(javax.slee.serviceactivity.ServiceStartedEvent event, ActivityContextInterface aci) {
logger.info("onServiceStartedEvent invoked.");
try {
// check if it's my service that is starting
ServiceActivity sa = ((ServiceActivityFactory) myEnv.lookup("slee/serviceactivity/factory")).getActivity();
if (sa.equals(aci.getActivity())) {
logger.info("Performing sanity check...");
logger.info("Provider [" + provider + "]");
logger.info("Message Factory [" + messageFactory + "]");
logger.info("AVP Factory [" + avpFactory + "]");
logger.info("Check completed. Result: " + ((provider != null ? 1 : 0) + (messageFactory != null ? 1 : 0) + (avpFactory != null ? 1 : 0)) + "/3");
logger.info("Connected to " + provider.getPeerCount() + " peers.");
for (DiameterIdentity peer : provider.getConnectedPeers()) {
logger.info("Connected to Peer[" + peer.toString() + "]");
}
// Initialize properties
Properties props = new Properties();
props.load(this.getClass().getClassLoader().getResourceAsStream("example.properties"));
this.originIP = props.getProperty("origin.ip") == null ? this.originIP : props.getProperty("origin.ip");
this.originPort = props.getProperty("origin.port") == null ? this.originPort : props.getProperty("origin.port");
this.originRealm = props.getProperty("origin.realm") == null ? this.originRealm : props.getProperty("origin.realm");
this.destinationIP = props.getProperty("destination.ip") == null ? this.destinationIP : props.getProperty("destination.ip");
this.destinationPort = props.getProperty("destination.port") == null ? this.destinationPort : props.getProperty("destination.port");
this.destinationRealm = props.getProperty("destination.realm") == null ? this.destinationRealm : props.getProperty("destination.realm");
this.actAsServer = props.getProperty("example.mode") == null ? this.actAsServer : !props.getProperty("example.mode").trim().equals("client");
logger.info("Diameter CCA Example :: Initialized in " + (actAsServer ? "SERVER" : "CLIENT") + " mode.");
if (actAsServer) {
TimerOptions options = new TimerOptions();
timerFacility.setTimer(aci, null, System.currentTimeMillis() + 30000, options);
}
}
} catch (Exception e) {
logger.error("Failure initializing Service.", e);
}
}
public void onTimerEvent(TimerEvent event, ActivityContextInterface aci) {
doSendEventCCR();
}
public void onCreditControlRequest(CreditControlRequest request, ActivityContextInterface aci) {
if (logger.isInfoEnabled())
logger.info("Received Credit-Control-Request (Application-Id[" + request.getHeader().getApplicationId() + "].");
// INITIAL_REQUEST(1), UPDATE_REQUEST(2), TERMINATION_REQUEST(3),
// EVENT_REQUEST(4)
CreditControlServerSession session = (CreditControlServerSession) aci.getActivity();
CreditControlAnswer answer = null;
switch (request.getCcRequestType().getValue()) {
case 1:
try {
if (logger.isInfoEnabled())
logger.info("Got INITIAL_REQUEST(1).");
if (getSentInitialAnswer()) {
logger.error("Error. Initial answer already sent! Aborting.");
return;
}
answer = session.createCreditControlAnswer();
answer.setResultCode(2001);
if (logger.isInfoEnabled()) {
logger.info("Processed Credit-Control-Request:\n" + request);
logger.info("Sending Credit-Control-Answer:\n" + answer);
}
session.sendCreditControlAnswer(answer);
this.setSentInitialAnswer(true);
} catch (Exception e) {
logger.error("Failed to create/send Credit-Control-Answer to reply INITIAL_REQUEST(1).", e);
}
break;
case 2:
try {
if (logger.isInfoEnabled())
logger.info("Got UPDATE_REQUEST(2).");
if (getSentUpdateAnswer()) {
logger.error("Error. Update answer already sent! Aborting.");
return;
}
answer = session.createCreditControlAnswer();
answer.setResultCode(2001);
if (logger.isInfoEnabled()) {
logger.info("Processed Credit-Control-Request:\n" + request);
logger.info("Sending Credit-Control-Answer:\n" + answer);
}
session.sendCreditControlAnswer(answer);
setSentUpdateAnswer(true);
} catch (Exception e) {
logger.error("Failed to create/send Credit-Control-Answer to reply UPDATE_REQUEST(2).", e);
}
break;
case 3:
try {
if (logger.isInfoEnabled())
logger.info("Got TERMINATION_REQUEST(3).");
if (getSentTerminationAnswer()) {
logger.error("Error. Termination answer already sent! Aborting.");
return;
}
answer = session.createCreditControlAnswer();
answer.setResultCode(2001);
if (logger.isInfoEnabled()) {
logger.info("Processed Credit-Control-Request:\n" + request);
logger.info("Sending Credit-Control-Answer:\n" + answer);
}
session.sendCreditControlAnswer(answer);
setSentTerminationAnswer(true);
} catch (Exception e) {
logger.error("Failed to create/send Credit-Control-Answer to reply TERMINATION_REQUEST(3).", e);
}
break;
case 4:
try {
if (logger.isInfoEnabled())
logger.info("Got EVENT_REQUEST(4).");
answer = session.createCreditControlAnswer();
answer.setResultCode(2001);
if (logger.isInfoEnabled())
logger.info("Sending Credit-Control-Answer:\n" + answer);
session.sendCreditControlAnswer(answer);
} catch (Exception e) {
logger.error("Failed to create/send Credit-Control-Answer to reply EVENT_REQUEST(4).", e);
}
break;
default:
logger.error("Unexpected CC-Request-Type in message: " + request.getCcRequestType() + ". Aborting...");
}
}
public void onCreditControlAnswer(CreditControlAnswer answer, ActivityContextInterface aci) {
logger.info("Received CCA with Result-Code[" + answer.getResultCode() + "].");
}
// ##########################################################################
// ## PRIVATE METHODS ##
// ##########################################################################
private void doSendEventCCR() {
try {
CreditControlClientSession session = this.provider.createClientSession();
ActivityContextInterface localACI = this.acif.getActivityContextInterface(session);
localACI.attach(this.getSbbContext().getSbbLocalObject());
CreditControlRequest request = session.createCreditControlRequest();
List<DiameterAvp> avps = new ArrayList<DiameterAvp>();
avps.add(avpFactory.getBaseFactory().createAvp(Avp.ORIGIN_HOST, ("aaa://" + originIP + ":" + originPort).getBytes()));
avps.add(avpFactory.getBaseFactory().createAvp(Avp.ORIGIN_REALM, originRealm.getBytes()));
avps.add(avpFactory.getBaseFactory().createAvp(Avp.DESTINATION_HOST, ("aaa://" + destinationIP + ":" + destinationPort).getBytes()));
avps.add(avpFactory.getBaseFactory().createAvp(Avp.DESTINATION_REALM, destinationRealm.getBytes()));
avps.add(avpFactory.getBaseFactory().createAvp(CreditControlAVPCodes.CC_Request_Type, 4l));
avps.add(avpFactory.getBaseFactory().createAvp(CreditControlAVPCodes.CC_Request_Number, 0l));
RequestedServiceUnitAvp rsu = this.avpFactory.createRequestedServiceUnit();
CcMoneyAvp ccMoney = this.avpFactory.createCcMoney();
ccMoney.setCurrencyCode(100);
ccMoney.setUnitValue(this.avpFactory.createUnitValue());
rsu.setCreditControlInputOctets(10);
rsu.setCreditControlMoneyAvp(ccMoney);
rsu.setCreditControlServiceSpecificUnits(1000);
rsu.setCreditControlTime(100);
rsu.setCreditControlTotalOctets(5000);
avps.add(rsu);
avps.add(avpFactory.getBaseFactory().createAvp(CreditControlAVPCodes.Requested_Action, 0));
// Now create & send
request.setExtensionAvps(avps.toArray(new DiameterAvp[avps.size()]));
if (logger.isInfoEnabled())
logger.info("About to send:\n" + request);
session.sendCreditControlRequest(request);
} catch (Exception e) {
logger.error("Failed to create/send Credit-Control-Request.", e);
}
}
// CMPS:
public abstract void setSentInitialAnswer(boolean b);
public abstract boolean getSentInitialAnswer();
public abstract void setSentUpdateAnswer(boolean b);
public abstract boolean getSentUpdateAnswer();
public abstract void setSentTerminationAnswer(boolean b);
public abstract boolean getSentTerminationAnswer();
}