001: package examples.nistgoodies.leakaudit;
002:
003: import gov.nist.javax.sip.SipStackImpl;
004:
005: import javax.sip.*;
006: import java.util.Timer;
007: import java.util.Properties;
008: import java.util.TimerTask;
009: import java.util.Set;
010:
011: /**
012: * This example demonstrates how an application can monitor the SIP Stack
013: * for leaked dialogs and transactions.
014: * <p/>
015: * This code is in the public domain.
016: *
017: * @author R. Borba (Natural Convergence)
018: */
019: public class LeakAudit {
020:
021: /// SIP Stack objects
022: protected static SipStack sipStack;
023: protected static ListeningPoint listeningPoint;
024: protected static SipProvider sipProvider;
025:
026: /// Test timer
027: private static Timer timer = new Timer();
028:
029: /// Interval between audits
030: private static long auditIntervalInMillis = 5000;
031:
032: /// The leaking application
033: private static LeakingApp leakingApp;
034:
035: /// Initializes the stack and starts the periodic audit
036: public static void init() {
037: // Create an application that leaks resources
038: leakingApp = new LeakingApp();
039:
040: // Create and initialize the SIP Stack
041: Properties properties = new Properties();
042: properties.setProperty("javax.sip.STACK_NAME",
043: "Leak Audit Sample");
044: properties.setProperty("javax.sip.IP_ADDRESS", "127.0.0.1");
045: initSipStack(properties, leakingApp);
046:
047: // Start a few dialogs
048: leakingApp.sendRequest();
049: leakingApp.sendRequest();
050: leakingApp.sendRequest();
051:
052: // Start monitoring the health of the internal threads
053: startAudit();
054:
055: // Sleep for a while so we can see some good audit reports being generated
056: sleep(2 * auditIntervalInMillis);
057:
058: // Leak a dialog into the stack
059: leakingApp.leakDialog();
060:
061: // Sleep again to see if we're able to detect the listening point thread going away
062: sleep(20 * auditIntervalInMillis);
063:
064: System.out.println("Done!");
065: System.exit(0);
066: }
067:
068: /// Creates and initializes the SIP Stack
069: private static void initSipStack(Properties properties,
070: SipListener sipListener) {
071: // Create the SIP Stack
072: SipFactory l_oSipFactory = SipFactory.getInstance();
073: l_oSipFactory.resetFactory();
074: l_oSipFactory.setPathName("gov.nist");
075: try {
076: sipStack = l_oSipFactory.createSipStack(properties);
077: } catch (PeerUnavailableException e) {
078: System.err
079: .println("could not find \"gov.nist.jain.protocol.ip.sip.SipStackImpl\" in the classpath");
080: e.printStackTrace();
081: System.err.println(e.getMessage());
082: System.exit(0);
083: }
084:
085: // Create a UDP listening point
086: try {
087: listeningPoint = sipStack.createListeningPoint("127.0.0.1",
088: 5060, "UDP");
089: } catch (Exception e) {
090: System.err.println("Failed to create UDP listening point");
091: e.printStackTrace();
092: System.exit(0);
093: }
094:
095: // Create a SIP Provider
096: try {
097: sipProvider = sipStack.createSipProvider(listeningPoint);
098: sipProvider.addSipListener(sipListener);
099: } catch (Exception e) {
100: System.err.println("Failed to create sip provider");
101: e.printStackTrace();
102: System.exit(0);
103: }
104:
105: }
106:
107: /// Sleeps for a while
108: private static void sleep(long millis) {
109: try {
110: Thread.sleep(millis);
111: } catch (InterruptedException e) {
112: System.err.println("Can't sleep");
113: e.printStackTrace();
114: System.exit(0);
115: }
116: }
117:
118: // Kicks off the periodic audit
119: private static void startAudit() {
120: /// Timer class used to periodically audit the stack
121: class AuditTimer extends TimerTask {
122: /// Action to be performed by this timer task
123: public final void run() {
124: // That's all we need to do in order to check if there's any dialog or transaction leak
125: Set activeCallIDs = leakingApp.getActiveCallIDs();
126: String auditReport = ((SipStackImpl) sipStack)
127: .auditStack(activeCallIDs, 30 * 1000, // Note: We're using an unrealistically short value just for this test.
128: // For real applications, see the suggested values in the README.txt.
129: 60 * 1000);
130: if (auditReport != null) {
131: System.out.println("--> RED ALERT!!! "
132: + auditReport);
133: } else {
134: System.out.println("--> No leaks detected.");
135: }
136:
137: // Schedule the next audit
138: timer.schedule(new AuditTimer(), auditIntervalInMillis);
139: }
140: }
141:
142: // Kick off the audit timer
143: timer.schedule(new AuditTimer(), auditIntervalInMillis);
144: }
145:
146: /// Entry point
147: public static void main(String[] args) throws Exception {
148: init();
149: }
150: }
|