package org.mobicents.mgcp.stack.test.concurrency;
import jain.protocol.ip.mgcp.CreateProviderException;
import jain.protocol.ip.mgcp.JainMgcpCommandEvent;
import jain.protocol.ip.mgcp.JainMgcpEvent;
import jain.protocol.ip.mgcp.JainMgcpListener;
import jain.protocol.ip.mgcp.JainMgcpResponseEvent;
import jain.protocol.ip.mgcp.message.Constants;
import jain.protocol.ip.mgcp.message.CreateConnection;
import jain.protocol.ip.mgcp.message.CreateConnectionResponse;
import jain.protocol.ip.mgcp.message.DeleteConnection;
import jain.protocol.ip.mgcp.message.NotificationRequest;
import jain.protocol.ip.mgcp.message.parms.CallIdentifier;
import jain.protocol.ip.mgcp.message.parms.ConnectionDescriptor;
import jain.protocol.ip.mgcp.message.parms.ConnectionIdentifier;
import jain.protocol.ip.mgcp.message.parms.ConnectionMode;
import jain.protocol.ip.mgcp.message.parms.EndpointIdentifier;
import jain.protocol.ip.mgcp.message.parms.EventName;
import jain.protocol.ip.mgcp.message.parms.RequestedAction;
import jain.protocol.ip.mgcp.message.parms.RequestedEvent;
import jain.protocol.ip.mgcp.pkg.MgcpEvent;
import jain.protocol.ip.mgcp.pkg.PackageName;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TooManyListenersException;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.log4j.Logger;
import org.mobicents.mgcp.stack.JainMgcpExtendedListener;
import org.mobicents.mgcp.stack.JainMgcpStackImpl;
import org.mobicents.mgcp.stack.JainMgcpStackProviderImpl;
import org.mobicents.mgcp.stack.test.TestHarness;
public class CA extends TestHarness implements JainMgcpExtendedListener {
private static Logger logger = Logger.getLogger(CA.class);
protected static final String CLIENT_ADDRESS = "127.0.0.1";
protected static final String SERVER_ADDRESS = "127.0.0.1";
protected static final int CA_PORT = 2724;
protected static final int MGW_PORT = 2729;
static int NDIALOGS = 50000;
static int MAXCONCURRENTCRCX = 15;
// a ramp-up period is required for performance testing.
int deleteCount = -100;
protected InetAddress caIPAddress = null;
protected InetAddress mgIPAddress = null;
protected JainMgcpStackImpl caStack = null;
private int ENDPOINT_ID = 1;
AtomicInteger nbConcurrentInvite = new AtomicInteger(0);
private JainMgcpStackProviderImpl caProvider;
long start = 0l;
private static Timer timer;
static {
timer = new Timer();
}
// //////////////////////////////////
// //// Listeners Method start /////
// /////////////////////////////////
public void transactionEnded(int handle) {
// TODO Auto-generated method stub
}
public void transactionRxTimedOut(JainMgcpCommandEvent command) {
System.out.println("Transaction Request Time out");
fail("Unexpected event: Rx TimeoutEvent ");
}
public void transactionTxTimedOut(JainMgcpCommandEvent command) {
System.out.println("Transaction Time out");
fail("Unexpected event: TimeoutEvent ");
}
public void processMgcpCommandEvent(JainMgcpCommandEvent jainmgcpcommandevent) {
// TODO Auto-generated method stub
}
public void processMgcpResponseEvent(JainMgcpResponseEvent jainmgcpresponseevent) {
Appdata appdatad = (Appdata) jainmgcpresponseevent.getSource();
EndpointIdentifier endpointID = new EndpointIdentifier(appdatad.getEndpointId(), SERVER_ADDRESS + ":"
+ MGW_PORT);
switch (jainmgcpresponseevent.getObjectIdentifier()) {
case Constants.RESP_CREATE_CONNECTION:
CreateConnectionResponse crcxResp = (CreateConnectionResponse) jainmgcpresponseevent;
if (logger.isDebugEnabled()) {
logger.debug("Received CRCX Response Tx Id = " + crcxResp.getTransactionHandle() + " Connection ID = "
+ crcxResp.getConnectionIdentifier());
}
appdatad.setReceivedCrcxResponse(true);
ConnectionIdentifier connectionIdentifier = crcxResp.getConnectionIdentifier();
appdatad.setConnectionIdentifier(connectionIdentifier);
// send RQNT
NotificationRequest notificationRequest = new NotificationRequest(appdatad, endpointID, caProvider
.getUniqueRequestIdentifier());
notificationRequest.setTransactionHandle(caProvider.getUniqueTransactionHandler());
RequestedAction[] actions = new RequestedAction[] { RequestedAction.NotifyImmediately };
RequestedEvent[] requestedEvents = {
new RequestedEvent(new EventName(PackageName.Announcement, MgcpEvent.oc, connectionIdentifier),
actions),
new RequestedEvent(new EventName(PackageName.Announcement, MgcpEvent.of, connectionIdentifier),
actions) };
notificationRequest.setRequestedEvents(requestedEvents);
if (logger.isDebugEnabled()) {
logger.debug("Sending RQNT Tx Id = " + notificationRequest.getTransactionHandle() + " Connection ID = "
+ connectionIdentifier);
}
caProvider.sendMgcpEvents(new JainMgcpEvent[] { notificationRequest });
break;
case Constants.RESP_NOTIFICATION_REQUEST:
if (logger.isDebugEnabled()) {
logger.debug("Received RQNT Response Tx Id = " + jainmgcpresponseevent.getTransactionHandle()
+ " Connection ID = " + appdatad.getConnectionIdentifier());
}
appdatad.setReceivedRqntResponse(true);
// Send DLCX
DeleteConnection deleteConnection = new DeleteConnection(appdatad, endpointID);
deleteConnection.setConnectionIdentifier(appdatad.getConnectionIdentifier());
deleteConnection.setTransactionHandle(caProvider.getUniqueTransactionHandler());
if (logger.isDebugEnabled()) {
logger.debug("Sending DLCX Tx Id = " + deleteConnection.getTransactionHandle() + " Connection ID = "
+ appdatad.getConnectionIdentifier());
}
caProvider.sendMgcpEvents(new JainMgcpEvent[] { deleteConnection });
break;
case Constants.RESP_DELETE_CONNECTION:
if (logger.isDebugEnabled()) {
logger.debug("Received DLCX Response Tx Id = " + jainmgcpresponseevent.getTransactionHandle()
+ " Connection ID = " + appdatad.getConnectionIdentifier());
}
appdatad.setReceivedDlcxResponse(true);
int ndialogs = nbConcurrentInvite.decrementAndGet();
// System.out.println(nbConcurrentInvite);
if (ndialogs > MAXCONCURRENTCRCX) {
System.out.println("Concurrent invites = " + ndialogs);
}
synchronized (this) {
if (ndialogs < MAXCONCURRENTCRCX / 2)
this.notify();
}
this.deleteCount++;
if (this.deleteCount == NDIALOGS) {
long current = System.currentTimeMillis();
float sec = (float) (current - start) / 1000f;
logger.info("Total time in sec = " + sec);
logger.info("Thrupt = " + (float) (NDIALOGS / sec));
System.out.println("Total time in sec = " + sec);
System.out.println("Thrupt = " + (float) (NDIALOGS / sec));
}
break;
default:
System.out.println("This RESPONSE is unexpected " + jainmgcpresponseevent);
logger.error("This RESPONSE is unexpected " + jainmgcpresponseevent);
break;
}
}
// //////////////////////////////////
// //// Listeners Method over //////
// /////////////////////////////////
public void createMgcpStack(JainMgcpListener listener) throws UnknownHostException, CreateProviderException,
TooManyListenersException {
caIPAddress = InetAddress.getByName(CLIENT_ADDRESS);
caStack = new JainMgcpStackImpl(caIPAddress, CA_PORT);
caProvider = (JainMgcpStackProviderImpl) caStack.createProvider();
caProvider.addJainMgcpListener(listener);
}
public void sendCreateConnection() {
try {
CallIdentifier callID = caProvider.getUniqueCallIdentifier();
if (ENDPOINT_ID == 11) {
ENDPOINT_ID = 1;
}
EndpointIdentifier endpointID = new EndpointIdentifier("media/trunk/Announcement/enp-" + ENDPOINT_ID++,
SERVER_ADDRESS + ":" + MGW_PORT);
String endpointName = endpointID.getLocalEndpointName();
Appdata appdata = new Appdata(endpointName);
CreateConnection createConnection = new CreateConnection(appdata, callID, endpointID,
ConnectionMode.SendRecv);
String sdpData = "v=0\r\n" + "o=4855 13760799956958020 13760799956958020" + " IN IP4 127.0.0.1\r\n"
+ "s=mysession session\r\n" + "p=+46 8 52018010\r\n" + "c=IN IP4 127.0.0.1\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";
createConnection.setRemoteConnectionDescriptor(new ConnectionDescriptor(sdpData));
createConnection.setTransactionHandle(caProvider.getUniqueTransactionHandler());
nbConcurrentInvite.incrementAndGet();
if (logger.isDebugEnabled()) {
logger.debug("Sending CRCX Tx Id = " + createConnection.getTransactionHandle());
}
caProvider.sendMgcpEvents(new JainMgcpEvent[] { createConnection });
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
fail("Unexpected Exception " + e.getMessage());
}
}
class Appdata {
protected TTask ttask;
protected long startTime;
protected long endTime;
private ConnectionIdentifier connectionIdentifier = null;
private boolean receivedCrcxResponse = false;
private boolean receivedRqntResponse = false;
private boolean receivedDlcxResponse = false;
String endpointId = null;
Appdata(String endpointId) {
this.endpointId = endpointId;
ttask = new TTask(this);
timer.schedule(ttask, 20 * 1000 * NDIALOGS / 100);
startTime = System.currentTimeMillis();
}
public void setReceivedCrcxResponse(boolean response) {
if (!receivedRqntResponse && !receivedDlcxResponse) {
this.receivedCrcxResponse = response;
} else {
System.out.println("receivedCrcxResponse after receivedRqntResponse or receivedDlcxResponse");
System.out.println("System falsed " + this.toString());
System.exit(0);
}
}
public void setReceivedRqntResponse(boolean response) {
if (receivedCrcxResponse && !receivedDlcxResponse) {
this.receivedRqntResponse = response;
} else {
System.out.println("receivedRqntResponse after receivedDlcxResponse or before receivedCrcxResponse");
System.out.println("System falsed " + this.toString());
System.exit(0);
}
}
public void setReceivedDlcxResponse(boolean response) {
if (receivedCrcxResponse && receivedRqntResponse) {
this.receivedDlcxResponse = response;
} else {
System.out.println("receivedDlcxResponse before receivedCrcxResponse or receivedDlcxResponse");
System.out.println("System falsed " + this.toString());
System.exit(0);
}
}
public TTask getTtask() {
return ttask;
}
public void setTtask(TTask ttask) {
this.ttask = ttask;
}
public String getEndpointId() {
return endpointId;
}
public void setEndpointId(String endpointId) {
this.endpointId = endpointId;
}
public boolean isReceivedCrcxResponse() {
return receivedCrcxResponse;
}
public boolean isReceivedRqntResponse() {
return receivedRqntResponse;
}
public boolean isReceivedDlcxResponse() {
return receivedDlcxResponse;
}
public void cancelTimer() {
this.ttask.cancel();
endTime = System.currentTimeMillis();
}
public String toString() {
return new StringBuffer("EndpointId = ").append(this.endpointId).append(" receivedCrcxResponse = ").append(
receivedCrcxResponse).append(" receivedRqntResponse= ").append(receivedRqntResponse).append(
" receivedDlcxResponse= ").append(receivedDlcxResponse).toString();
}
public ConnectionIdentifier getConnectionIdentifier() {
return connectionIdentifier;
}
public void setConnectionIdentifier(ConnectionIdentifier connectionIdentifier) {
this.connectionIdentifier = connectionIdentifier;
}
}
class TTask extends TimerTask {
Appdata appdata;
public TTask(Appdata appdata) {
this.appdata = appdata;
}
public void run() {
if (!this.appdata.isReceivedCrcxResponse() || !this.appdata.isReceivedDlcxResponse()
|| !this.appdata.isReceivedRqntResponse()) {
System.out.println("Appdata " + appdata.toString());
logger.info("Appdata " + appdata.toString());
System.exit(0);
} else {
this.appdata = null;
}
}
}
public static void main(String args[]) {
int noOfCalls = Integer.parseInt(args[0]);
int noOfConcurrentCalls = Integer.parseInt(args[1]);
System.out.println("Number calls to be completed = " + noOfCalls
+ " Number of concurrent calls to be maintained = " + noOfConcurrentCalls);
logger.info("Number calls to be completed = " + noOfCalls + " Number of concurrent calls to be maintained = "
+ noOfConcurrentCalls);
NDIALOGS = noOfCalls;
MAXCONCURRENTCRCX = noOfConcurrentCalls;
final CA ca = new CA();
try {
ca.createMgcpStack(ca);
ca.start = System.currentTimeMillis();
while (ca.deleteCount < NDIALOGS) {
while (ca.nbConcurrentInvite.intValue() >= MAXCONCURRENTCRCX) {
System.out.println("nbConcurrentInvite = " + ca.nbConcurrentInvite.intValue()
+ " Waiting for max CRCX count to go down!");
logger.info("nbConcurrentInvite = " + ca.nbConcurrentInvite.intValue()
+ " Waiting for max CRCX count to go down!");
synchronized (ca) {
try {
ca.wait();
} catch (Exception ex) {
}
}
}
if (ca.deleteCount == 0) {
ca.start = System.currentTimeMillis();
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
}
ca.sendCreateConnection();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (CreateProviderException e) {
e.printStackTrace();
} catch (TooManyListenersException e) {
e.printStackTrace();
}
}
}