Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
  * Conditions Of Use
  *
  * This software was developed by employees of the National Institute of
  * Standards and Technology (NIST), and others.
  * This software is has been contributed to the public domain.
  * As a result, a formal license is not needed to use the software.
  *
  * This software is provided "AS IS."
 * NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
 * AND DATA ACCURACY.  NIST does not warrant or make any representations
 * regarding the use of the software or the results thereof, including but
 * not limited to the correctness, accuracy, reliability or usefulness of
 * the software.
 *
 *
 */
 package test.tck.msgflow;
 
 import  junit.framework.*;
 
 import javax.sip.*;
 import java.util.*;
 import test.tck.*;

Tests whether the dialog state machine is properly implemented. Dialog state machines are far less complex than transaction FSMs. All they do is passively change states without producing any automatic responses or retransmissions. Therefore we're only testing one scenario per Dialog (one for Server generated and one for Client generated dialogs. Distinction is made server and client generated scenarios are likely to be navigated by server and client transactions respectively and not by a single entity)

Title: TCK

Description: JAIN SIP 1.1 Technology Compatibility Kit

Author(s):
Emil Ivov Network Research Team, Louis Pasteur University, Strasbourg, France. This code is in the public domain.
Version:
1.0
 
 
 public class DialogStateMachineTest extends MessageFlowHarness {
 
     public DialogStateMachineTest(String name) {
         super(name,true);   // enable auto-dialog support
     }
     //==================== tests ==============================
     
Tests state transitions of a server side dialog
 
     public void testClientDialogStates() {
         try {
             Request invite = createTiInviteRequest(nullnullnull);
             ClientTransaction tran = null;
             //Send an invite request
             try {
                 .collectRequestEvent();
                 tran = .getNewClientTransaction(invite);
                 tran.sendRequest();
             } catch (TooManyListenersException e) {
                 throw new TckInternalError(
                     "Failed to register a listener with the RI",
                     e);
             } catch (SipException e) {
                 throw new TiUnexpectedError(
                     "Failed to send initial invite request",
                     e);
             }
             //Wait for the invite to arrive
             waitForMessage();
             RequestEvent inviteReqEvt =
                 .extractCollectedRequestEvent();
             if (inviteReqEvt == null || inviteReqEvt.getRequest() == null)
                 throw new TiUnexpectedError("The TI did not send the initial invite request");
             //get the dialog
             Dialog dialog = tran.getDialog();
             //We should have a null state here
             assertNull(
                 "A dialog passed into the "
                     + dialog.getState()
                     + " state before receiving any response!",
                 dialog.getState());
 
             //We will now send RINGING response and see that the Dialog enters an early state
             //start listening for the response
             try {
                 .collectResponseEvent();
             } catch (TooManyListenersException e) {
                 throw new TiUnexpectedError(
                     "Failed to register a SipListener with the TI.",
                     e);
             }
             Response ringing = null;
            try {
                ringing =
                    .createResponse(
                        .,
                        inviteReqEvt.getRequest());
                ((ToHeaderringing.getHeader(.)).setTag(
                    Integer.toString(hashCode()));
                // BUG: set contact header on dialog-creating response
                ringing.setHeader(createRiContact());
                .sendResponse(ringing);
            } catch (Exception e) {
                throw new TckInternalError(
                    "Failed to create and send a RINGING response",
                    e);
            }
            waitForMessage();
            ResponseEvent ringingRespEvt =
                .extractCollectedResponseEvent();
            if (ringingRespEvt == null || ringingRespEvt.getResponse() == null)
                throw new TiUnexpectedError("The TI did not pass RINGING response to the TU.");
            //The dialog should now be in its early state.
            assertEquals(
                "The Dialog did not pass into the early state upon reception of a RINGING response",
                .,
                dialog.getState());
            // JvB: @todo Test that UPDATE (or PRACK) requests during early dialog
            // dont make dialog CONFIRMED
            /*
            Request update = null;
            try {
                eventCollector.collectRequestEvent(riSipProvider);
                update = dialog.createRequest( "UPDATE" );
                update.setHeader(createTiContact());
                dialog.sendRequest( tiSipProvider.getNewClientTransaction(update) );
            } catch (Exception e) {
                throw new TckInternalError(
                    "Failed to create and send an UPDATE request",
                    e);
            }
            waitForMessage();
            RequestEvent updateEvt =
                eventCollector.extractCollectedRequestEvent();
            if (updateEvt == null || updateEvt.getRequest() == null)
                throw new TiUnexpectedError("The TI did not send the UPDATE request");
            //The dialog should still be in its EARLY state.
            assertEquals(
                "The Dialog did not stay in the EARLY state upon reception of an UPDATE request",
                DialogState.EARLY,
                dialog.getState());
            // finish the UPDATE
            riSipProvider.sendResponse( riMessageFactory.createResponse(200, updateEvt.getRequest()) );
            */
            //We will now send OK response and see that the Dialog enters a CONFIRMED state
            //start listening for the response
            try {
                .collectResponseEvent();
            } catch (TooManyListenersException e) {
                throw new TiUnexpectedError(
                    "Failed to register a SipListener with the TI.",
                    e);
            }
            Response ok = null;
            try {
                ok =
                    .createResponse(
                        .,
                        inviteReqEvt.getRequest());
                ((ToHeaderok.getHeader(.)).setTag(
                    Integer.toString(hashCode()));
                // BUG: set contact header on dialog-creating response
                ok.setHeader(createRiContact());
                .sendResponse(ok);
            } catch (Exception e) {
                throw new TckInternalError(
                    "Failed to create and send a OK response",
                    e);
            }
            waitForMessage();
            ResponseEvent okRespEvt =
                .extractCollectedResponseEvent();
            if (okRespEvt == null || okRespEvt.getResponse() == null)
                throw new TiUnexpectedError("The TI did not pass OK response to the TU.");
            //The dialog should now be in its confirmed state.
            assertEquals(
                "The Dialog did not pass into the CONFIRMED state upon reception of an OK response",
                .,
                dialog.getState());
            //Say bye and go COMPLETED
            Request bye = null;
            try {
                bye = dialog.createRequest(.);
                ClientTransaction byeTran =
                    .getNewClientTransaction(bye);
                dialog.sendRequest(byeTran);
            } catch (SipException e) {
                throw new TiUnexpectedError(
                    "Failed to create and send a BYE request using a dialog.",
                    e);
            }
            // Send response before checking that the state goes to
            // terminated state.
            waitForMessage();
            waitForMessage();
            assertTrue(
                "The dialog did not pass into a final ( TERMINATED) state after getting OK for a BYE.",
                 ..equals(dialog.getState()));
        } catch (Throwable exc) {
            exc.printStackTrace();
            fail(exc.getClass().getName() + ": " + exc.getMessage());
        }
        assertTrue(new Exception().getStackTrace()[0].toString(), true);
    }

    
Tests state transitions of a client side dialog
    public void testServerDialogStates() {
        try {
            ClientTransaction inviteTransaction = null;
            Request invite = createRiInviteRequest(nullnullnull);
            //Send an invite request
            try {
                .collectRequestEvent();
                // riSipProvider.sendRequest(invite);
                // Made this stateful
                inviteTransaction = .getNewClientTransaction(invite);
                inviteTransaction.sendRequest();
            } catch (TooManyListenersException exc) {
                throw new TiUnexpectedError(
                    "Failed to register a listener with the TI",
                    exc);
            } catch (SipException exc) {
                throw new TckInternalError(
                    "Failed to send initial invite request",
                    exc);
            }
            //Wait for the invite to arrive
            waitForMessage();
            RequestEvent inviteReqEvt =
                .extractCollectedRequestEvent();
            if (inviteReqEvt == null || inviteReqEvt.getRequest() == null)
                throw new TiUnexpectedError("The TI did not dispatch the initial invite request");
            //Create a transaction
            ServerTransaction tran = null;
            try {
                tran =
                    .getNewServerTransaction(
                        inviteReqEvt.getRequest());
            } catch (Exception ex) {
                throw new TiUnexpectedError("The TI failed to create a Server transaction for an incoming request");
            }
            //get the dialog
            Dialog dialog = tran.getDialog();
            // We should have a null state here
            assertNull(
                "A dialog passed into the "
                    + dialog.getState()
                    + " state before sending any response!",
                dialog.getState());
            //We will now send RINGING response and see that the Dialog enters an early state
            //start listening for the response
            try {
                .collectResponseEvent();
            } catch (TooManyListenersException e) {
                throw new TckInternalError(
                    "Failed to register a SipListener with the RI.",
                    e);
            }
            Response ringing = null;
            try {
                ringing =
                    .createResponse(
                        .,
                        inviteReqEvt.getRequest());
                //!discuss with Ranga
                ((ToHeaderringing.getHeader(.)).setTag(
                    Integer.toString(hashCode()));
                // BUG report by Ben Evans (Open cloud):
                // set contact header on dialog-creating response
                ringing.setHeader(createTiContact());
                tran.sendResponse(ringing);
            } catch (Exception e) {
                throw new TiUnexpectedError(
                    "Failed to create and send a RINGING response",
                    e);
            }
            waitForMessage();
            ResponseEvent ringingRespEvt =
                .extractCollectedResponseEvent();
            if (ringingRespEvt == null || ringingRespEvt.getResponse() == null)
                throw new TiUnexpectedError("The TI did not send the RINGING response.");
            //The dialog should now be in its early state.
            assertEquals(
                "The Dialog did not pass into the early state after sending a RINGING response",
                .,
                dialog.getState());
            //We will now send an OK response and see that the Dialog enters a CONFIRMED state
            //start listening for the response
            SipEventCollector tteCollector = new SipEventCollector();
            try {
                .collectResponseEvent();
                // JvB: Also receive TransactionTerminated event
                tteCollector.collectTransactionTermiatedEvent();
            } catch (TooManyListenersException e) {
                throw new TckInternalError(
                    "Failed to register a SipListener with the RI.",
                    e);
            }
            Response ok = null;
            try {
                ok =
                    .createResponse(
                        .,
                        inviteReqEvt.getRequest());
                // Bug - need to set to-tag on OK response
                // NIST-SIP fills in the to-tag but this behaviour is
                // not specified
                ((ToHeaderok.getHeader(.)).setTag(
                    Integer.toString(hashCode()));
                ContactHeader contact = createTiContact();
                ok.addHeader(contact);
                tran.sendResponse(ok);
            } catch (Exception e) {
                throw new TiUnexpectedError(
                    "Failed to create and send an OK response",
                    e);
            }
            waitForMessage();
            ResponseEvent okRespEvt =
                .extractCollectedResponseEvent();
            if (okRespEvt == null || okRespEvt.getResponse() == null)
                throw new TiUnexpectedError("The TI did not send an OK response.");
            ClientTransaction ct = okRespEvt.getClientTransaction();
            // JvB: With auto-dialog-support OFF, this returns *null* !
            Dialog clientDialog = ct.getDialog();
            assertNotNullclientDialog );
            Request ackReq = clientDialog.createAck( ( (CSeqHeader)okRespEvt.getResponse().getHeader(.)).getSeqNumber());;
            clientDialog.sendAck(ackReq);
            waitForMessage();
            //The dialog should now be in its CONFIRMED state.
            assertEquals(
                "The Dialog did not pass into the CONFIRMED state upon reception of an OK response",
                .,
                dialog.getState());
            // After sending 2xx, there should be a ServerTransactionTerminated event at UAS side
            waitForTimeout();   // May take up to 64*T1 seconds
            TransactionTerminatedEvent tte = tteCollector.extractCollectedTransactionTerminatedEvent();
            assertNotNulltte );
            assertTruette.isServerTransaction() );
            assertEqualstrantte.getServerTransaction() );
            //Say bye from the RI and see that TI goes COMPLETED
            //it is the ri that should say bye here as we are testing dialog navigation
            //by server transactions
            try {
                .collectRequestEvent();
            } catch (TooManyListenersException ex) {
                throw new TiUnexpectedError(
                    "Failed to register a SipListener with the TI",
                    ex);
            }
            try {
                // Ranga - use the dialog here.
                Dialog d = inviteTransaction.getDialog();
                Request bye = d.createRequest(.);
                ct = .getNewClientTransaction(bye);
                d.sendRequest(ct);
            } catch (Exception e) {
                throw new TckInternalError(
                    "Failed to create and send a BYE request using a dialog.",
                    e);
            }
            waitForMessage();
            RequestEvent byeEvt = .extractCollectedRequestEvent();
            if (byeEvt == null || byeEvt.getRequest() == null)
                throw new TiUnexpectedError("The TI did not dispatch a BYE request");
            ServerTransaction byeTran = null;

            
This should be in the transaction try { byeTran = tiSipProvider.getNewServerTransaction(byeEvt.getRequest()); } catch (TransactionUnavailableException ex) { // Could have already fielded the bye - in which case a // transaction for the BYE cannot be created. ex.printStackTrace(); assertTrue(new Exception().getStackTrace()[0].toString(), true); } catch(Exception ex) { ex.printStackTrace(); System.out.println("Failed to create a transaction for an incoming bye request."); }
            byeTran = (ServerTransactionbyeEvt.getServerTransaction();
            //We will now send an OK response and see that the
            // Dialog enters a COMPLETED/TERMINATED state
            //start listening for the response
            try {
                .collectResponseEvent();
            } catch (TooManyListenersException e) {
                throw new TckInternalError(
                    "Failed to register a SipListener with the RI.",
                    e);
            }
            try {
                ok =
                    .createResponse(
                        .,
                        byeEvt.getRequest());
                ok.addHeader(createTiContact());
                byeTran.sendResponse(ok);
            } catch (Exception e) {
                throw new TiUnexpectedError(
                    "Failed to create and send an OK response",
                    e);
            }
            waitForMessage();
            ResponseEvent byeOkRespEvt =
                .extractCollectedResponseEvent();
            if (byeOkRespEvt == null || byeOkRespEvt.getResponse() == null)
                throw new TiUnexpectedError("The TI did not send an OK response to a bye request.");
            //The dialog should now be in the COMPLETED/TERMINATED state.
            assertTrue(
                "The dialog did not pass into a final (COMPLETED or TERMINATED) state after recieving a BYE.",
                ..equals(dialog.getState())
                    || ..equals(dialog.getState()));
        } catch (Throwable exc) {
            exc.printStackTrace();
            fail(exc.getClass().getName() + ": " + exc.getMessage());
        }
        assertTrue(new Exception().getStackTrace()[0].toString(), true);
    }
    //==================== end of tests
    //====== STATIC JUNIT ==========
    public static Test suite() {
        return new TestSuite(DialogStateMachineTest.class);
    }
New to GrepCode? Check out our FAQ X