All Downloads are FREE. Search and download functionalities are using the official Maven repository.

test.unit.gov.nist.javax.sip.stack.RFC5626KeepAliveTest Maven / Gradle / Ivy

There is a newer version: 1.3.0-91
Show newest version
package test.unit.gov.nist.javax.sip.stack;

import gov.nist.javax.sip.DialogTimeoutEvent;
import gov.nist.javax.sip.IOExceptionEventExt;
import gov.nist.javax.sip.IOExceptionEventExt.Reason;
import gov.nist.javax.sip.ListeningPointExt;
import gov.nist.javax.sip.ListeningPointImpl;
import gov.nist.javax.sip.SipListenerExt;
import gov.nist.javax.sip.SipStackImpl;
import gov.nist.javax.sip.stack.ConnectionOrientedMessageChannel;
import gov.nist.javax.sip.stack.ConnectionOrientedMessageProcessor;
import gov.nist.javax.sip.stack.MessageProcessor;
import gov.nist.javax.sip.stack.SIPTransactionStack;
import gov.nist.javax.sip.stack.TCPMessageChannel;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.sip.ClientTransaction;
import javax.sip.Dialog;
import javax.sip.DialogTerminatedEvent;
import javax.sip.IOExceptionEvent;
import javax.sip.ListeningPoint;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipProvider;
import javax.sip.TimeoutEvent;
import javax.sip.Transaction;
import javax.sip.TransactionTerminatedEvent;
import javax.sip.address.Address;
import javax.sip.address.SipURI;
import javax.sip.header.CSeqHeader;
import javax.sip.header.CallIdHeader;
import javax.sip.header.ContactHeader;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.FromHeader;
import javax.sip.header.Header;
import javax.sip.header.MaxForwardsHeader;
import javax.sip.header.ToHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;

import org.apache.log4j.Logger;
import static test.tck.TestHarness.assertTrue;
import test.tck.msgflow.callflows.AssertUntil;
import test.tck.msgflow.callflows.NetworkPortAssigner;

import test.tck.msgflow.callflows.ProtocolObjects;
import test.tck.msgflow.callflows.ScenarioHarness;
import test.tck.msgflow.callflows.TestAssertion;

/**
 * Test for RFC 5626 Section 4.4.1 tests the various conditions outlined in the flow available at  
 * https://docs.google.com/drawings/d/1vWHQU4Xqy_gkbsprJ8gumoBi2ajdFw71uw_5vrn2V8g/edit?hl=en_US
 * 
 * @author [email protected]
 * @author : Alex Vinogradov
 */
public class RFC5626KeepAliveTest extends ScenarioHarness implements SipListenerExt {

    protected Shootist shootist;
    
    protected Shootme shootme;
    
    private static final int TIMEOUT = 50000;    

    private static Logger logger = Logger.getLogger("test.tck");

    static {
        if (!logger.isAttached(console)) {
            logger.addAppender(console);
        }
    }

    class Shootme  implements SipListenerExt {


        private ProtocolObjects  protocolObjects;
        private ListeningPoint listeningPoint;

        // To run on two machines change these to suit.
        public static final String myAddress = "127.0.0.1";

        public final int myPort = NetworkPortAssigner.retrieveNextPort();

        private ServerTransaction inviteTid;


        private Dialog dialog;

        private ServerTransaction reSendSt = null;
        private Response reSendResponse = null;
        private int dropAckCount = 0;


        private boolean keepAliveTimeoutFired;

        public Shootme(ProtocolObjects protocolObjects) {
            this.protocolObjects = protocolObjects;
            ((SIPTransactionStack)protocolObjects.sipStack).setReliableConnectionKeepAliveTimeout(4000);
        }
        
        public ConnectionOrientedMessageProcessor getTestMessageProcessor() {
            return (ConnectionOrientedMessageProcessor)((ListeningPointImpl) shootme.listeningPoint).getMessageProcessor();
        }
        
        public ConnectionOrientedMessageChannel getTestChannel() {
            try {
                MessageProcessor processor = ((ListeningPointImpl) shootme.listeningPoint).getMessageProcessor();
                Field field = ConnectionOrientedMessageProcessor.class.getDeclaredField("messageChannels");
                field.setAccessible(true);

                Map tcpMessageChannels = (Map) field.get(processor);
                Iterator itr = tcpMessageChannels.values().iterator();
                while (itr.hasNext()) {
                    ConnectionOrientedMessageChannel tcpMessageChannel = itr.next();
                    logger.info("tcpMessageChannel port " + tcpMessageChannel.getPort() + " peerPort " + tcpMessageChannel.getPeerPort());                  
                }
                return tcpMessageChannels.values().iterator().next();
            } catch (Exception e) {
                e.printStackTrace();
                fail(e.getMessage(), e);
                return null;
            }
        }

        public void processRequest(RequestEvent requestEvent) {
            Request request = requestEvent.getRequest();
            ServerTransaction serverTransactionId = requestEvent
                    .getServerTransaction();

            logger.info("\n\nRequest " + request.getMethod()
                    + " received at " + protocolObjects.sipStack.getStackName()
                    + " with server transaction id " + serverTransactionId);

            if (request.getMethod().equals(Request.INVITE)) {
                processInvite(requestEvent, serverTransactionId);
            } 

        }        

        /**
         * Process the invite request.
         */
        public void processInvite(RequestEvent requestEvent,
                ServerTransaction serverTransaction) {
            SipProvider sipProvider = (SipProvider) requestEvent.getSource();
            Request request = requestEvent.getRequest();
            logger.info("Got an INVITE  " + request);
            try {
                Response response = protocolObjects.messageFactory.createResponse(180, request);
                ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
                toHeader.setTag("4321");
                Address address = protocolObjects.addressFactory.createAddress("Shootme ");
                ContactHeader contactHeader = protocolObjects.headerFactory
                        .createContactHeader(address);
                response.addHeader(contactHeader);
                ServerTransaction st = requestEvent.getServerTransaction();

                if (st == null) {
                    st = sipProvider.getNewServerTransaction(request);
                    logger.info("Server transaction created!" + request);

                    logger.info("Dialog = " + st.getDialog());
                }

                byte[] content = request.getRawContent();
                if (content != null) {
                    logger.info(" content = " + new String(content));
                    ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory
                            .createContentTypeHeader("application", "sdp");
                    logger.info("response = " + response);
                    response.setContent(content, contentTypeHeader);
                }
                dialog = st.getDialog();
                if (dialog != null) {
                    logger.info("Dialog " + dialog);
                    logger.info("Dialog state " + dialog.getState());
                }
                st.sendResponse(response);
                response = protocolObjects.messageFactory.createResponse(200, request);
                toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
                toHeader.setTag("4321");
                // Application is supposed to set.
                response.addHeader(contactHeader);
                st.sendResponse(response);
                reSendSt = st;
                reSendResponse = response;
                logger.info("TxState after sendResponse = " + st.getState());
                this.inviteTid = st;
            } catch (Exception ex) {
                String s = "unexpected exception";

                logger.error(s,ex);
                AckReTransmissionTest.fail(s);
            }
        }


        public void processResponse(ResponseEvent responseReceivedEvent) {
            logger.info("Got a response");
            Response response = (Response) responseReceivedEvent.getResponse();
            Transaction tid = responseReceivedEvent.getClientTransaction();

            logger.info("Response received with client transaction id "
                    + tid + ":\n" + response);
            try {
                if (response.getStatusCode() == Response.OK
                        && ((CSeqHeader) response.getHeader(CSeqHeader.NAME))
                                .getMethod().equals(Request.INVITE)) {
                    Dialog dialog = tid.getDialog();
                    CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
                    Request ackRequest = dialog.createAck(cseq.getSeqNumber());
                    dialog.sendAck(ackRequest);
                }
                if ( tid != null ) {
                    Dialog dialog = tid.getDialog();
                    logger.info("Dialog State = " + dialog.getState());
                }
            } catch (Exception ex) {
                String s = "Unexpected exception";
                logger.error(s,ex);
                AckReTransmissionTest.fail(s);
            }

        }

        public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
            Transaction transaction;
            if (timeoutEvent.isServerTransaction()) {
                transaction = timeoutEvent.getServerTransaction();
            } else {
                transaction = timeoutEvent.getClientTransaction();
            }
            logger.info("state = " + transaction.getState());
            logger.info("dialog = " + transaction.getDialog());
            logger.info("dialogState = "
                    + transaction.getDialog().getState());
            logger.info("Transaction Time out");
        }




        public SipProvider createSipProvider() throws Exception {
            listeningPoint = protocolObjects.sipStack.createListeningPoint(myAddress,
                    myPort, protocolObjects.transport);


            SipProvider sipProvider = protocolObjects.sipStack.createSipProvider(listeningPoint);
            return sipProvider;
        }




        public void checkState() {
            AckReTransmissionTest.assertTrue("ACK was not successfully retransmitted 4 times", 4==dropAckCount);
        }
        /*
         * (non-Javadoc)
         *
         * @see javax.sip.SipListener#processIOException(javax.sip.IOExceptionEvent)
         */
        public void processIOException(IOExceptionEvent exceptionEvent) {
            logger.info("Shootme An IO Exception was detected : "
                    + exceptionEvent.getHost());
            keepAliveTimeoutFired |= (exceptionEvent instanceof IOExceptionEventExt && ((IOExceptionEventExt)exceptionEvent).getReason() == Reason.KeepAliveTimeout);

            logger.info("Shootme KeepAlive Time out " + keepAliveTimeoutFired);         
        }

        /*
         * (non-Javadoc)
         *
         * @see javax.sip.SipListener#processTransactionTerminated(javax.sip.TransactionTerminatedEvent)
         */
        public void processTransactionTerminated(
                TransactionTerminatedEvent transactionTerminatedEvent) {
            logger.info("Tx terminated event ");

        }

        /*
         * (non-Javadoc)
         *
         * @see javax.sip.SipListener#processDialogTerminated(javax.sip.DialogTerminatedEvent)
         */
        public void processDialogTerminated(
                DialogTerminatedEvent dialogTerminatedEvent) {
            logger.info("Dialog terminated event detected ");

        }


        public void processDialogTimeout(DialogTimeoutEvent timeoutEvent) {
            // TODO Auto-generated method stub
            
        }       
    }
    
    class Shootist implements SipListenerExt {
        
        private final Shootme shootme;

        private SipProvider provider;

        private ContactHeader contactHeader;

        private ListeningPoint listeningPoint;

        // To run on two machines change these to suit.
        public static final String myAddress = "127.0.0.1";

        public final int myPort = NetworkPortAssigner.retrieveNextPort();

        protected ClientTransaction inviteTid;

        private ProtocolObjects protocolObjects;

        private Dialog dialog;
        
        Timer timer = new Timer();

        class MyTimerTask extends TimerTask {            
            private int keepAliveSent = 0;
            
            @Override
            public void run() {                

//                assertTrue(shootist.getTestMessageProcessor().setKeepAliveTimeout(
//                        Shootme.myAddress, Shootme.myPort, 1000));
                logger.info("keepAliveSent =" + keepAliveSent + " / KeepAliveToSend ="+keepAliveToSend);
                
                if(((SipStackImpl)shootist.protocolObjects.sipStack).isAlive() && (keepAliveToSend < 0 || keepAliveSent <= keepAliveToSend)) {
                    try {
                        ((ListeningPointExt)shootist.listeningPoint).sendHeartbeat( shootme.myAddress, shootme.myPort);
                        keepAliveSent++;
                    } catch (Exception e) {
                        logger.info("keepAliveSender received Exception =" + e + " ,cancelling keepalivesender timer");
                        e.printStackTrace();
                        this.cancel();
//                      fail();
                    }
                    if(keepAliveSent > keepAliveToSend) {
                        ((SIPTransactionStack)protocolObjects.sipStack).setKeepAliveTimeout(myAddress, myPort, transport, shootme.myAddress, shootme.myPort, -1);   
                    }
                } else {
                    this.cancel();
                }
            }
        };
        
        public Shootist(ProtocolObjects protocolObjects,Shootme shootme) {
            super();
            this.protocolObjects = protocolObjects;
            ((SIPTransactionStack)protocolObjects.sipStack).setReliableConnectionKeepAliveTimeout(4000);
            this.shootme = shootme;
        }


        public void processRequest(RequestEvent requestReceivedEvent) {
        }


        public void processResponse(ResponseEvent responseReceivedEvent) {
            logger.info("Got a response");

            Response response = (Response) responseReceivedEvent.getResponse();
            Transaction tid = responseReceivedEvent.getClientTransaction();

            logger.info("Response received with client transaction id " + tid
                    + ":\n" + response.getStatusCode());
            if (tid != null) {
                logger.info("Dialog = " + responseReceivedEvent.getDialog());
                logger.info("Dialog State is "
                        + responseReceivedEvent.getDialog().getState());
            }
            SipProvider provider = (SipProvider) responseReceivedEvent.getSource();

            try {
                if (response.getStatusCode() == Response.OK
                        && ((CSeqHeader) response.getHeader(CSeqHeader.NAME))
                                .getMethod().equals(Request.INVITE)) {

                    Dialog dialog = responseReceivedEvent.getDialog();
                    CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
                    Request ackRequest = dialog.createAck(cseq.getSeqNumber());
                    logger.info("Ack request to send = " + ackRequest);
                    logger.info("Sending ACK");
                    dialog.sendAck(ackRequest);
                }
            } catch (Exception ex) {
                logger.error(ex);
                ex.printStackTrace();
                RFC5626KeepAliveTest.fail("unexpected exception");
            }
            timer.schedule(new MyTimerTask(), 1000, 3000);
        }

        public volatile boolean keepAliveTimeoutFired;

        public int keepAliveToSend = -1;

        public void processTimeout(TimeoutEvent timeoutEvent) {

            
        }

        public SipProvider createSipProvider() {
            try {
                listeningPoint = protocolObjects.sipStack.createListeningPoint(
                        myAddress, myPort, protocolObjects.transport);

                provider = protocolObjects.sipStack
                        .createSipProvider(listeningPoint);

                return provider;
            } catch (Exception ex) {
                logger.error(ex);
                fail("unable to create provider");
                return null;
            }
        }

        public void sendInvite() {

            try {

                // Note that a provider has multiple listening points.
                // all the listening points must have the same IP address
                // and port but differ in their transport parameters.

                String fromName = "BigGuy";
                String fromSipAddress = "here.com";
                String fromDisplayName = "The Master Blaster";

                String toSipAddress = "there.com";
                String toUser = "LittleGuy";
                String toDisplayName = "The Little Blister";

                // create >From Header
                SipURI fromAddress = protocolObjects.addressFactory.createSipURI(
                        fromName, fromSipAddress);

                Address fromNameAddress = protocolObjects.addressFactory
                        .createAddress(fromAddress);
                fromNameAddress.setDisplayName(fromDisplayName);
                FromHeader fromHeader = protocolObjects.headerFactory
                        .createFromHeader(fromNameAddress, new Integer((int) (Math
                                .random() * Integer.MAX_VALUE)).toString());

                // create To Header
                SipURI toAddress = protocolObjects.addressFactory.createSipURI(
                        toUser, toSipAddress);
                Address toNameAddress = protocolObjects.addressFactory
                        .createAddress(toAddress);
                toNameAddress.setDisplayName(toDisplayName);
                ToHeader toHeader = protocolObjects.headerFactory.createToHeader(
                        toNameAddress, null);

                // create Request URI addressed to me
                SipURI requestURI = protocolObjects.addressFactory.createSipURI(
                        toUser, shootme.myAddress + ":" + shootme.myPort);

                // Create ViaHeaders

                ArrayList viaHeaders = new ArrayList();
                int port = provider.getListeningPoint(protocolObjects.transport)
                        .getPort();

                ViaHeader viaHeader = protocolObjects.headerFactory
                        .createViaHeader(myAddress, port,
                                protocolObjects.transport, null);

                // add via headers
                viaHeaders.add(viaHeader);

                // Create ContentTypeHeader
                ContentTypeHeader contentTypeHeader = protocolObjects.headerFactory
                        .createContentTypeHeader("application", "sdp");

                // Create a new CallId header
                CallIdHeader callIdHeader = provider.getNewCallId();
                // JvB: Make sure that the implementation matches the messagefactory
                callIdHeader = protocolObjects.headerFactory.createCallIdHeader(callIdHeader.getCallId());


                // Create a new Cseq header
                CSeqHeader cSeqHeader = protocolObjects.headerFactory
                        .createCSeqHeader(1L, Request.INVITE);

                // Create a new MaxForwardsHeader
                MaxForwardsHeader maxForwards = protocolObjects.headerFactory
                        .createMaxForwardsHeader(70);

                // Create the request.
                Request request = protocolObjects.messageFactory.createRequest(
                        requestURI, Request.INVITE, callIdHeader, cSeqHeader,
                        fromHeader, toHeader, viaHeaders, maxForwards);
                // Create contact headers

                // Create the contact name address.
                SipURI contactURI = protocolObjects.addressFactory.createSipURI(
                        fromName, myAddress);
                contactURI.setPort(provider.getListeningPoint(
                        protocolObjects.transport).getPort());

                Address contactAddress = protocolObjects.addressFactory
                        .createAddress(contactURI);

                // Add the contact address.
                contactAddress.setDisplayName(fromName);

                contactHeader = protocolObjects.headerFactory
                        .createContactHeader(contactAddress);
                request.addHeader(contactHeader);

                // Add the extension header.
                Header extensionHeader = protocolObjects.headerFactory
                        .createHeader("My-Header", "my header value");
                request.addHeader(extensionHeader);

                String sdpData = "v=0\r\n"
                        + "o=4855 13760799956958020 13760799956958020"
                        + " IN IP4  129.6.55.78\r\n" + "s=mysession session\r\n"
                        + "p=+46 8 52018010\r\n" + "c=IN IP4  129.6.55.78\r\n"
                        + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n"
                        + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n"
                        + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n";

                request.setContent(sdpData, contentTypeHeader);

                // The following is the preferred method to route requests
                // to the peer. Create a route header and set the "lr"
                // parameter for the router header.

//                Address address = protocolObjects.addressFactory
//                        .createAddress("");
//                // SipUri sipUri = (SipUri) address.getURI();
//                // sipUri.setPort(PEER_PORT);
//
//                RouteHeader routeHeader = protocolObjects.headerFactory
//                        .createRouteHeader(address);
//                ((SipURI) address.getURI()).setLrParam();
//                request.addHeader(routeHeader);
                extensionHeader = protocolObjects.headerFactory.createHeader(
                        "My-Other-Header", "my new header value ");
                request.addHeader(extensionHeader);

                Header callInfoHeader = protocolObjects.headerFactory.createHeader(
                        "Call-Info", "");
                request.addHeader(callInfoHeader);

                // Create the client transaction.
                this.inviteTid = provider.getNewClientTransaction(request);
                this.dialog = this.inviteTid.getDialog();
                // Note that the response may have arrived right away so
                // we cannot check after the message is sent.
                assertTrue(this.dialog.getState() == null);

                // send the request out.
                this.inviteTid.sendRequest();

            } catch (Exception ex) {
                logger.error("Unexpected exception", ex);
                fail("unexpected exception");
            }
        }

        TCPMessageChannel getTestChannel() {
            try {
                MessageProcessor processor = ((ListeningPointImpl) shootist.listeningPoint).getMessageProcessor();
                Field field = ConnectionOrientedMessageProcessor.class.getDeclaredField("messageChannels");
                field.setAccessible(true);

                Map tcpMessageChannels = (Map) field.get(processor);
                return tcpMessageChannels.values().iterator().next();
            } catch (Exception e) {
                e.printStackTrace();
                fail(e.getMessage(), e);
                return null;
            }
        }

        ConnectionOrientedMessageProcessor getTestMessageProcessor() {
            return (ConnectionOrientedMessageProcessor)((ListeningPointImpl) shootist.listeningPoint).getMessageProcessor();
        }


        /*
         * (non-Javadoc)
         *
         * @see javax.sip.SipListener#processIOException(javax.sip.IOExceptionEvent)
         */
        public void processIOException(IOExceptionEvent exceptionEvent) {
            logger.info("Shootist IO Exception ! ");
            keepAliveTimeoutFired |= (exceptionEvent instanceof IOExceptionEventExt && ((IOExceptionEventExt)exceptionEvent).getReason() == Reason.KeepAliveTimeout);

            logger.info("Shootist KeepAlive Time out " + keepAliveTimeoutFired);              
        }

        /*
         * (non-Javadoc)
         *
         * @see javax.sip.SipListener#processTransactionTerminated(javax.sip.TransactionTerminatedEvent)
         */
        public void processTransactionTerminated(
                TransactionTerminatedEvent transactionTerminatedEvent) {

            logger.info("Transaction Terminated Event!");
        }

        /*
         * (non-Javadoc)
         *
         * @see javax.sip.SipListener#processDialogTerminated(javax.sip.DialogTerminatedEvent)
         */
        public void processDialogTerminated(
                DialogTerminatedEvent dialogTerminatedEvent) {
            logger.info("Dialog Terminated Event!");

        }

        public void processDialogTimeout(DialogTimeoutEvent timeoutEvent) {
            // TODO Auto-generated method stub
            
        }       
    }

    public RFC5626KeepAliveTest() {
        super("KeepAlive", true);
    }

    public void setUp() throws NoSuchFieldException {
    }

    public void testKeepaliveTCP() throws InterruptedException {
        try {
            this.transport = "tcp";

            super.setUp();


            shootme = new Shootme(getTiProtocolObjects());
            SipProvider shootmeProvider = shootme.createSipProvider();
            providerTable.put(shootmeProvider, shootme);
            
            shootist = new Shootist(getRiProtocolObjects(), shootme);
            SipProvider shootistProvider = shootist.createSipProvider();
            providerTable.put(shootistProvider, shootist);            
            
            shootistProvider.addSipListener(this);
            shootmeProvider.addSipListener(this);
        } catch (Exception ex) {
            ex.printStackTrace();
            fail("unexpected exception ");
        }        
        shootist.sendInvite();
        
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        assertTrue(
            AssertUntil.assertUntil(new TestAssertion() {
                @Override
                public boolean assertCondition() {
                    return !shootist.keepAliveTimeoutFired &&
                            !shootme.keepAliveTimeoutFired;
                };
            }, TIMEOUT)
        );        
    }
    
    public void testKeepaliveTCPShootmeTimeout() throws InterruptedException {
        try {
            this.transport = "tcp";

            super.setUp();

            shootme = new Shootme(getTiProtocolObjects());
            SipProvider shootmeProvider = shootme.createSipProvider();
            providerTable.put(shootmeProvider, shootme);

            shootist = new Shootist(getRiProtocolObjects(), shootme);
            SipProvider shootistProvider = shootist.createSipProvider();
            providerTable.put(shootistProvider, shootist);            
            
            shootistProvider.addSipListener(this);
            shootmeProvider.addSipListener(this);
        } catch (Exception ex) {
            ex.printStackTrace();
            fail("unexpected exception ");
        }        
        shootist.keepAliveToSend  = 1;
        shootist.sendInvite();
        
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        assertTrue( 
            AssertUntil.assertUntil(new TestAssertion() {
                @Override
                public boolean assertCondition() {
                    return !shootist.keepAliveTimeoutFired &&
                            shootme.keepAliveTimeoutFired;
                };
            }, TIMEOUT)
        ); 
    }
    
    public void testKeepaliveTCPShootistTimeout() throws Exception {       
        this.transport = "tcp";

        super.setUp();

        shootme = new Shootme(getTiProtocolObjects());
        SipProvider shootmeProvider = shootme.createSipProvider();
        providerTable.put(shootmeProvider, shootme);
        
        shootist = new Shootist(getRiProtocolObjects(), shootme);
        SipProvider shootistProvider = shootist.createSipProvider();
        providerTable.put(shootistProvider, shootist);        
        
        shootistProvider.addSipListener(this);
        shootmeProvider.addSipListener(this);
                    
        shootist.keepAliveToSend  = 100;
        shootist.sendInvite();
        
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        assertTrue( 
            AssertUntil.assertUntil(new TestAssertion() {
                @Override
                public boolean assertCondition() {
                    return !shootist.keepAliveTimeoutFired &&
                            !shootme.keepAliveTimeoutFired;
                };
            }, TIMEOUT)
        ); 
        
        System.out.println("Destroying Shootme to provoke timeout on Shootist");
        
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        getTiProtocolObjects().destroy();

        assertTrue( 
            AssertUntil.assertUntil(new TestAssertion() {
                @Override
                public boolean assertCondition() {
                    return shootist.keepAliveTimeoutFired &&
                           !shootme.keepAliveTimeoutFired;
                };
            }, TIMEOUT)
        );          
    }

    public void testKeepaliveTCPModifyKeepAliveTimeout() throws Exception {
        this.transport = "tcp";

        super.setUp();

        shootme = new Shootme(getTiProtocolObjects());
        SipProvider shootmeProvider = shootme.createSipProvider();
        providerTable.put(shootmeProvider, shootme);

        shootist = new Shootist(getRiProtocolObjects(),shootme);
        SipProvider shootistProvider = shootist.createSipProvider();
        providerTable.put(shootistProvider, shootist);        
        
        shootistProvider.addSipListener(this);
        shootmeProvider.addSipListener(this);
        shootist.keepAliveToSend  = 100;
        shootist.sendInvite();        

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        assertFalse(this.shootist.keepAliveTimeoutFired);
        assertFalse(this.shootme.keepAliveTimeoutFired);     
      
        shootist.keepAliveToSend = 0;
        
        // cannot be found due to ephemeral port
//        assertTrue(shootme.getTestMessageProcessor().setKeepAliveTimeout(shootist.myAddress, shootist.myPort, 400));
        
        shootme.getTestChannel().setKeepAliveTimeout(400);

        try {
            Thread.sleep(600);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }        
        assertFalse(this.shootist.keepAliveTimeoutFired);
        assertTrue(this.shootme.keepAliveTimeoutFired);
    }

    public void tearDown() {
        try {           
            Thread.sleep(1000);            
            if (getTiProtocolObjects() != getRiProtocolObjects()) {
                getRiProtocolObjects().destroy();
            }            
            getTiProtocolObjects().destroy();
            Thread.sleep(1000);
            this.providerTable.clear();
            logTestCompleted();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void processRequest(RequestEvent requestEvent) {
        getSipListener(requestEvent).processRequest(requestEvent);

    }

    public void processResponse(ResponseEvent responseEvent) {
        getSipListener(responseEvent).processResponse(responseEvent);

    }

    public void processTimeout(TimeoutEvent timeoutEvent) {
        getSipListener(timeoutEvent).processTimeout(timeoutEvent);
    }

    public void processIOException(IOExceptionEvent exceptionEvent) {
         getSipListener(exceptionEvent).processIOException(exceptionEvent);
    }

    public void processTransactionTerminated(
            TransactionTerminatedEvent transactionTerminatedEvent) {
        getSipListener(transactionTerminatedEvent)
                .processTransactionTerminated(transactionTerminatedEvent);

    }

    public void processDialogTerminated(
            DialogTerminatedEvent dialogTerminatedEvent) {
        getSipListener(dialogTerminatedEvent).processDialogTerminated(
                dialogTerminatedEvent);

    }
    
    private SipListenerExt getSipListener(EventObject sipEvent) {
        SipProvider source = (SipProvider) sipEvent.getSource();
        SipListenerExt listener = (SipListenerExt) providerTable.get(source);
        assertTrue(listener != null);
        return listener;
    }

    public void processDialogTimeout(DialogTimeoutEvent timeoutEvent) {
        getSipListener(timeoutEvent).processDialogTimeout(timeoutEvent);
        
    }   
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy