/* * 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.examples.diameter; 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.DiameterActivity; 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.AccountingAnswer; import net.java.slee.resource.diameter.base.events.DiameterMessage; import net.java.slee.resource.diameter.base.events.avp.DiameterAvp; import net.java.slee.resource.diameter.base.events.avp.DiameterIdentity; import org.apache.log4j.Logger; import org.jdiameter.api.Avp; import org.jdiameter.api.ResultCode; import org.mobicents.slee.resource.diameter.base.AccountingServerSessionActivityImpl; /** * * DiameterExampleSbb.java * * <br> * Super project: mobicents <br> * 11:34:16 PM May 26, 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 abstract class DiameterExampleSbb implements javax.slee.Sbb { private static Logger logger = Logger.getLogger(DiameterExampleSbb.class); private SbbContext sbbContext = null; // This SBB's context private Context myEnv = null; // This SBB's environment private DiameterProvider provider = null; private DiameterMessageFactory messageFactory = null; private DiameterAvpFactory avpFactory = null; private TimerFacility timerFacility = null; private boolean actAsServer = false; 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 = "21812"; private String destinationRealm = "mobicents.org"; public void setSbbContext(SbbContext context) { logger.info("sbbRolledBack invoked."); this.sbbContext = context; try { myEnv = (Context) new InitialContext().lookup("java:comp/env"); provider = (DiameterProvider) myEnv.lookup("slee/resources/diameter-base-ra-acif"); logger.info("Got Provider:" + provider); messageFactory = provider.getDiameterMessageFactory(); logger.info("Got Message Factory:" + provider); avpFactory = provider.getDiameterAvpFactory(); logger.info("Got AVP Factory:" + provider); // 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() { 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("################################################################################"); logger.info("### D I A M E T E R E X A M P L E A P P L I C A T I O N :: S T A R T E D ##"); logger.info("################################################################################"); messageFactory = provider.getDiameterMessageFactory(); avpFactory = provider.getDiameterAvpFactory(); 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() + "]"); Properties props = new Properties(); props.load(this.getClass().getClassLoader().getResourceAsStream("example.properties")); this.actAsServer = props.getProperty("example.mode") == null ? this.actAsServer : !props.getProperty("example.mode").trim().equals("client"); 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"); logger.info("Diameter Base Example :: Initialized in " + (actAsServer ? "SERVER" : "CLIENT") + " mode."); if (!actAsServer) { TimerOptions options = new TimerOptions(); timerFacility.setTimer(aci, null, System.currentTimeMillis() + 30000, options); } /* * Basic message sending testing (DWR/DWA) * * try { DiameterAvp avp_DestHost = avpFactory.createAvp( * Avp.DESTINATION_HOST, "127.0.0.1".getBytes() ); DiameterAvp * avp_DestRealm = avpFactory.createAvp( Avp.DESTINATION_REALM, * "mobicents.org".getBytes() ); * * DiameterAvp avp_HostIPAddress = avpFactory.createAvp( * Avp.HOST_IP_ADDRESS, ("0x0001" + "7f000001").getBytes() ); * * DiameterAvp avp_VendorId = avpFactory.createAvp( * Avp.VENDOR_ID, "193".getBytes() ); DiameterAvp * avp_ProductName = avpFactory.createAvp( Avp.PRODUCT_NAME, * "jDiameter".getBytes() ); * * DiameterAvp[] avps = new DiameterAvp[]{avp_DestHost, * avp_DestRealm, avp_HostIPAddress, avp_VendorId, * avp_ProductName}; * * logger.info( "Creating Custom Message..." ); DiameterMessage * ms = messageFactory.createDeviceWatchdogRequest(avps); * logger.info( "Created Custom Message[" + ms + "]" ); * * logger.info( "Sending Custom Message..." ); * provider.createActivity().sendMessage( ms ); logger.info( * "Sent Custom Message[" + ms + "]" ); } catch (Exception e) { * logger.error( "Not working...", e ); } */ } } catch (Exception e) { logger.error("Unable to handle service started event...", e); } } public void onTimerEvent(TimerEvent event, ActivityContextInterface aci) { sendAccountingRequest(); } public void onAbortSessionRequest(net.java.slee.resource.diameter.base.events.AbortSessionRequest asr, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Abort-Session-Request received."); } public void onAbortSessionAnswer(net.java.slee.resource.diameter.base.events.AbortSessionAnswer asa, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Abort-Session-Answer received."); } public void onAccountingRequest(net.java.slee.resource.diameter.base.events.AccountingRequest acr, ActivityContextInterface aci) { long start = System.currentTimeMillis(); if (logger.isInfoEnabled()) logger.info("Accounting-Request received. [" + acr + "]"); boolean actAsProxy = false; try { // Are we gonna act as a proxy? if (actAsProxy) { // In here we act as a "proxy". Just for testing we take the // original message, // replace the Origin/Destination Host/Realm AVPs and send it to // the emulator. boolean hasDestinationHost = false; boolean hasDestinationRealm = false; List<DiameterAvp> avps = new ArrayList<DiameterAvp>(); for (DiameterAvp avp : acr.getAvps()) { switch (avp.getCode()) { case Avp.ORIGIN_HOST: avps.add(avpFactory.createAvp(Avp.ORIGIN_HOST, "aaa://"+originIP+":"+originPort.getBytes())); break; case Avp.ORIGIN_REALM: avps.add(avpFactory.createAvp(Avp.ORIGIN_REALM, originRealm.getBytes())); break; case Avp.DESTINATION_HOST: avps.add(avpFactory.createAvp(Avp.DESTINATION_HOST, "aaa://"+destinationIP+":"+destinationPort.getBytes())); hasDestinationHost = true; break; case Avp.DESTINATION_REALM: avps.add(avpFactory.createAvp(Avp.DESTINATION_REALM, destinationRealm.getBytes())); hasDestinationRealm = true; break; default: avps.add(avp); } } if (!hasDestinationHost) avps.add(avpFactory.createAvp(Avp.DESTINATION_HOST, "127.0.0.1".getBytes())); if (!hasDestinationRealm) avps.add(avpFactory.createAvp(Avp.DESTINATION_REALM, "mobicents.org".getBytes())); if (logger.isInfoEnabled()) logger.info("AVPs ==> " + avps); DiameterAvp[] avpArray = new DiameterAvp[avps.size()]; avpArray = avps.toArray(avpArray); if (logger.isInfoEnabled()) logger.info("Creating Custom Message..."); DiameterMessage ms = messageFactory.createAccountingRequest(avpArray); if (logger.isInfoEnabled()) { logger.info("Created Custom Message[" + ms + "]"); logger.info("Sending Custom Message..."); } provider.createActivity().sendMessage(ms); if (logger.isInfoEnabled()) logger.info("Sent Custom Message[" + ms + "]"); } else { // In here we act as a server and just say it's SUCCESS. if (aci.getActivity() instanceof AccountingServerSessionActivityImpl) { AccountingServerSessionActivityImpl assa = (AccountingServerSessionActivityImpl) aci.getActivity(); AccountingAnswer ans = assa.createAccountAnswer(acr, ResultCode.SUCCESS); if (logger.isInfoEnabled()) logger.info("Sending Accounting-Answer [" + ans + "]"); assa.sendAccountAnswer(ans); if (logger.isInfoEnabled()) logger.info("Accounting-Answer sent."); } } } catch (Exception e) { logger.error("", e); } long end = System.currentTimeMillis(); if (logger.isInfoEnabled()) logger.info("Accounting-Request proccessed. [" + (end - start) + "ms]"); } public void onAccountingAnswer(net.java.slee.resource.diameter.base.events.AccountingAnswer aca, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Accounting-Answer received."); } public void onCapabilitiesExchangeRequest(net.java.slee.resource.diameter.base.events.CapabilitiesExchangeRequest cer, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Capabilities-Exchange-Request received."); } public void onCapabilitiesExchangeAnswer(net.java.slee.resource.diameter.base.events.CapabilitiesExchangeAnswer cea, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Capabilities-Exchange-Answer received."); } public void onDeviceWatchdogRequest(net.java.slee.resource.diameter.base.events.DeviceWatchdogRequest dwr, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Device-Watchdog-Request received."); } public void onDeviceWatchdogAnswer(net.java.slee.resource.diameter.base.events.DeviceWatchdogAnswer dwa, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Device-Watchdog-Answer received."); } public void onDisconnectPeerRequest(net.java.slee.resource.diameter.base.events.DisconnectPeerRequest dpr, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Disconnect-Peer-Request received."); } public void onDisconnectPeerAnswer(net.java.slee.resource.diameter.base.events.DisconnectPeerAnswer dpa, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Disconnect-Peer-Answer received."); } public void onReAuthRequest(net.java.slee.resource.diameter.base.events.ReAuthRequest rar, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Re-Auth-Request received."); } public void onReAuthAnswer(net.java.slee.resource.diameter.base.events.ReAuthAnswer raa, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Re-Auth-Answer received."); } public void onSessionTerminationRequest(net.java.slee.resource.diameter.base.events.SessionTerminationRequest rar, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Session-Termination-Request received."); } public void onSessionTerminationAnswer(net.java.slee.resource.diameter.base.events.SessionTerminationAnswer raa, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Session-Termination-Answer received."); } public void onErrorAnswer(net.java.slee.resource.diameter.base.events.ErrorAnswer era, ActivityContextInterface aci) { if (logger.isInfoEnabled()) logger.info("Error-Answer received."); } // ########################################################################## // ## PRIVATE METHODS ## // ########################################################################## private void sendAccountingRequest() { try { DiameterActivity activity = provider.createActivity(); List<DiameterAvp> avps = new ArrayList<DiameterAvp>(); avps.add(avpFactory.createAvp(Avp.SESSION_ID, activity.getSessionId().getBytes())); DiameterAvp avpVendorId = avpFactory.createAvp(Avp.VENDOR_ID, 193); DiameterAvp avpAcctApplicationId = avpFactory.createAvp(Avp.ACCT_APPLICATION_ID, 19302); avps.add(avpFactory.createAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, new DiameterAvp[] { avpVendorId, avpAcctApplicationId })); avps.add(avpFactory.createAvp(Avp.ORIGIN_HOST, this.originIP.getBytes())); avps.add(avpFactory.createAvp(Avp.ORIGIN_REALM, this.originRealm.getBytes())); avps.add(avpFactory.createAvp(Avp.DESTINATION_HOST, (this.destinationIP + ":" + this.destinationPort).getBytes())); avps.add(avpFactory.createAvp(Avp.DESTINATION_REALM, this.destinationRealm.getBytes())); // Subscription ID DiameterAvp subscriptionIdType = avpFactory.createAvp(193, 555, 0); DiameterAvp subscriptionIdData = avpFactory.createAvp(193, 554, "00001000"); avps.add(avpFactory.createAvp(193, 553, new DiameterAvp[] { subscriptionIdType, subscriptionIdData })); // Requested Service Unit DiameterAvp unitType = avpFactory.createAvp(193, 611, 2); DiameterAvp valueDigits = avpFactory.createAvp(193, 617, 10L); DiameterAvp unitValue = avpFactory.createAvp(193, 612, new DiameterAvp[] { valueDigits }); avps.add(avpFactory.createAvp(193, 606, new DiameterAvp[] { unitType, unitValue })); // Record Number and Type avps.add(avpFactory.createAvp(Avp.ACC_RECORD_NUMBER, 0)); avps.add(avpFactory.createAvp(Avp.ACC_RECORD_TYPE, 1)); // Requested action avps.add(avpFactory.createAvp(193, 615, 0)); // Service Parameter Type DiameterAvp serviceParameterType = avpFactory.createAvp(193, 608, 0); DiameterAvp serviceParameterValue = avpFactory.createAvp(193, 609, "510"); avps.add(avpFactory.createAvp(193, 607, new DiameterAvp[] { serviceParameterType, serviceParameterValue })); // Service Parameter Type DiameterAvp serviceParameterType2 = avpFactory.createAvp(193, 608, 14); DiameterAvp serviceParameterValue2 = avpFactory.createAvp(193, 609, "20"); avps.add(avpFactory.createAvp(193, 607, new DiameterAvp[] { serviceParameterType2, serviceParameterValue2 })); DiameterAvp[] avpArray = new DiameterAvp[avps.size()]; avpArray = avps.toArray(avpArray); if (logger.isInfoEnabled()) logger.info("Creating Custom Message..."); DiameterMessage ms = messageFactory.createAccountingRequest(avpArray); if (logger.isInfoEnabled()) { logger.info("Created Custom Message[" + ms + "]"); logger.info("Sending Custom Message..."); } activity.sendMessage(ms); if (logger.isInfoEnabled()) logger.info("Sent Custom Message[" + ms + "]"); } catch (Exception e) { logger.error("", e); } } }