/protocols/jain-mgcp/stack/src/test/java/org/mobicents/protocols/mgcp/stack/test/concurrency/CA.java

http://mobicents.googlecode.com/ · Java · 457 lines · 309 code · 110 blank · 38 comment · 30 complexity · 51c74fe4a93bc0d4b14a48656e69b6a3 MD5 · raw file

  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2011, Red Hat, Inc. and individual contributors
  4. * by the @authors tag. See the copyright.txt in the distribution for a
  5. * full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.mobicents.protocols.mgcp.stack.test.concurrency;
  23. import jain.protocol.ip.mgcp.CreateProviderException;
  24. import jain.protocol.ip.mgcp.JainMgcpCommandEvent;
  25. import jain.protocol.ip.mgcp.JainMgcpEvent;
  26. import jain.protocol.ip.mgcp.JainMgcpListener;
  27. import jain.protocol.ip.mgcp.JainMgcpResponseEvent;
  28. import jain.protocol.ip.mgcp.message.Constants;
  29. import jain.protocol.ip.mgcp.message.CreateConnection;
  30. import jain.protocol.ip.mgcp.message.CreateConnectionResponse;
  31. import jain.protocol.ip.mgcp.message.DeleteConnection;
  32. import jain.protocol.ip.mgcp.message.NotificationRequest;
  33. import jain.protocol.ip.mgcp.message.parms.CallIdentifier;
  34. import jain.protocol.ip.mgcp.message.parms.ConnectionDescriptor;
  35. import jain.protocol.ip.mgcp.message.parms.ConnectionIdentifier;
  36. import jain.protocol.ip.mgcp.message.parms.ConnectionMode;
  37. import jain.protocol.ip.mgcp.message.parms.EndpointIdentifier;
  38. import jain.protocol.ip.mgcp.message.parms.EventName;
  39. import jain.protocol.ip.mgcp.message.parms.RequestedAction;
  40. import jain.protocol.ip.mgcp.message.parms.RequestedEvent;
  41. import jain.protocol.ip.mgcp.pkg.MgcpEvent;
  42. import jain.protocol.ip.mgcp.pkg.PackageName;
  43. import java.net.InetAddress;
  44. import java.net.UnknownHostException;
  45. import java.util.Timer;
  46. import java.util.TimerTask;
  47. import java.util.TooManyListenersException;
  48. import java.util.concurrent.atomic.AtomicInteger;
  49. import org.apache.log4j.Logger;
  50. import org.mobicents.protocols.mgcp.stack.JainMgcpExtendedListener;
  51. import org.mobicents.protocols.mgcp.stack.JainMgcpStackImpl;
  52. import org.mobicents.protocols.mgcp.stack.JainMgcpStackProviderImpl;
  53. import org.mobicents.protocols.mgcp.stack.test.TestHarness;
  54. public class CA extends TestHarness implements JainMgcpExtendedListener {
  55. private static Logger logger = Logger.getLogger(CA.class);
  56. protected static final String CLIENT_ADDRESS = "127.0.0.1";
  57. protected static final String SERVER_ADDRESS = "127.0.0.1";
  58. protected static final int CA_PORT = 2427;
  59. protected static final int MGW_PORT = 2727;
  60. static int NDIALOGS = 50000;
  61. static int MAXCONCURRENTCRCX = 15;
  62. // a ramp-up period is required for performance testing.
  63. int deleteCount = -100;
  64. protected InetAddress caIPAddress = null;
  65. protected InetAddress mgIPAddress = null;
  66. protected JainMgcpStackImpl caStack = null;
  67. private int ENDPOINT_ID = 1;
  68. AtomicInteger nbConcurrentInvite = new AtomicInteger(0);
  69. private JainMgcpStackProviderImpl caProvider;
  70. long start = 0l;
  71. private static Timer timer;
  72. static {
  73. timer = new Timer();
  74. }
  75. // //////////////////////////////////
  76. // //// Listeners Method start /////
  77. // /////////////////////////////////
  78. public void transactionEnded(int handle) {
  79. // TODO Auto-generated method stub
  80. }
  81. public void transactionRxTimedOut(JainMgcpCommandEvent command) {
  82. System.out.println("Transaction Request Time out");
  83. fail("Unexpected event: Rx TimeoutEvent ");
  84. }
  85. public void transactionTxTimedOut(JainMgcpCommandEvent command) {
  86. System.out.println("Transaction Time out \n"+ command);
  87. fail("Unexpected event: TimeoutEvent ");
  88. }
  89. public void processMgcpCommandEvent(JainMgcpCommandEvent jainmgcpcommandevent) {
  90. // TODO Auto-generated method stub
  91. }
  92. public void processMgcpResponseEvent(JainMgcpResponseEvent jainmgcpresponseevent) {
  93. Appdata appdatad = (Appdata) jainmgcpresponseevent.getSource();
  94. EndpointIdentifier endpointID = new EndpointIdentifier(appdatad.getEndpointId(), SERVER_ADDRESS + ":"
  95. + MGW_PORT);
  96. switch (jainmgcpresponseevent.getObjectIdentifier()) {
  97. case Constants.RESP_CREATE_CONNECTION:
  98. CreateConnectionResponse crcxResp = (CreateConnectionResponse) jainmgcpresponseevent;
  99. if (logger.isDebugEnabled()) {
  100. logger.debug("Received CRCX Response Tx Id = " + crcxResp.getTransactionHandle() + " Connection ID = "
  101. + crcxResp.getConnectionIdentifier());
  102. }
  103. appdatad.setReceivedCrcxResponse(true);
  104. ConnectionIdentifier connectionIdentifier = crcxResp.getConnectionIdentifier();
  105. appdatad.setConnectionIdentifier(connectionIdentifier);
  106. // send RQNT
  107. NotificationRequest notificationRequest = new NotificationRequest(appdatad, endpointID, caProvider
  108. .getUniqueRequestIdentifier());
  109. notificationRequest.setTransactionHandle(caProvider.getUniqueTransactionHandler());
  110. RequestedAction[] actions = new RequestedAction[] { RequestedAction.NotifyImmediately };
  111. RequestedEvent[] requestedEvents = {
  112. new RequestedEvent(new EventName(PackageName.Announcement, MgcpEvent.oc, connectionIdentifier),
  113. actions),
  114. new RequestedEvent(new EventName(PackageName.Announcement, MgcpEvent.of, connectionIdentifier),
  115. actions) };
  116. notificationRequest.setRequestedEvents(requestedEvents);
  117. if (logger.isDebugEnabled()) {
  118. logger.debug("Sending RQNT Tx Id = " + notificationRequest.getTransactionHandle() + " Connection ID = "
  119. + connectionIdentifier);
  120. }
  121. caProvider.sendMgcpEvents(new JainMgcpEvent[] { notificationRequest });
  122. break;
  123. case Constants.RESP_NOTIFICATION_REQUEST:
  124. if (logger.isDebugEnabled()) {
  125. logger.debug("Received RQNT Response Tx Id = " + jainmgcpresponseevent.getTransactionHandle()
  126. + " Connection ID = " + appdatad.getConnectionIdentifier());
  127. }
  128. appdatad.setReceivedRqntResponse(true);
  129. // Send DLCX
  130. DeleteConnection deleteConnection = new DeleteConnection(appdatad, endpointID);
  131. deleteConnection.setConnectionIdentifier(appdatad.getConnectionIdentifier());
  132. deleteConnection.setTransactionHandle(caProvider.getUniqueTransactionHandler());
  133. if (logger.isDebugEnabled()) {
  134. logger.debug("Sending DLCX Tx Id = " + deleteConnection.getTransactionHandle() + " Connection ID = "
  135. + appdatad.getConnectionIdentifier());
  136. }
  137. caProvider.sendMgcpEvents(new JainMgcpEvent[] { deleteConnection });
  138. break;
  139. case Constants.RESP_DELETE_CONNECTION:
  140. if (logger.isDebugEnabled()) {
  141. logger.debug("Received DLCX Response Tx Id = " + jainmgcpresponseevent.getTransactionHandle()
  142. + " Connection ID = " + appdatad.getConnectionIdentifier());
  143. }
  144. appdatad.setReceivedDlcxResponse(true);
  145. int ndialogs = nbConcurrentInvite.decrementAndGet();
  146. // System.out.println(nbConcurrentInvite);
  147. if (ndialogs > MAXCONCURRENTCRCX) {
  148. System.out.println("Concurrent invites = " + ndialogs);
  149. }
  150. synchronized (this) {
  151. if (ndialogs < MAXCONCURRENTCRCX / 2)
  152. this.notify();
  153. }
  154. this.deleteCount++;
  155. if (this.deleteCount == NDIALOGS) {
  156. long current = System.currentTimeMillis();
  157. float sec = (float) (current - start) / 1000f;
  158. logger.info("Total time in sec = " + sec);
  159. logger.info("Thrupt = " + (float) (NDIALOGS / sec));
  160. System.out.println("Total time in sec = " + sec);
  161. System.out.println("Thrupt = " + (float) (NDIALOGS / sec));
  162. }
  163. break;
  164. default:
  165. System.out.println("This RESPONSE is unexpected " + jainmgcpresponseevent);
  166. logger.error("This RESPONSE is unexpected " + jainmgcpresponseevent);
  167. break;
  168. }
  169. }
  170. // //////////////////////////////////
  171. // //// Listeners Method over //////
  172. // /////////////////////////////////
  173. public void createMgcpStack(JainMgcpListener listener) throws UnknownHostException, CreateProviderException,
  174. TooManyListenersException {
  175. caIPAddress = InetAddress.getByName(CLIENT_ADDRESS);
  176. caStack = new JainMgcpStackImpl(caIPAddress, CA_PORT);
  177. caProvider = (JainMgcpStackProviderImpl) caStack.createProvider();
  178. caProvider.addJainMgcpListener(listener);
  179. }
  180. public void sendCreateConnection() {
  181. try {
  182. CallIdentifier callID = caProvider.getUniqueCallIdentifier();
  183. if (ENDPOINT_ID == 11) {
  184. ENDPOINT_ID = 1;
  185. }
  186. EndpointIdentifier endpointID = new EndpointIdentifier("media/trunk/Announcement/enp-" + ENDPOINT_ID++,
  187. SERVER_ADDRESS + ":" + MGW_PORT);
  188. String endpointName = endpointID.getLocalEndpointName();
  189. Appdata appdata = new Appdata(endpointName);
  190. CreateConnection createConnection = new CreateConnection(appdata, callID, endpointID,
  191. ConnectionMode.SendRecv);
  192. String sdpData = "v=0\r\n" + "o=4855 13760799956958020 13760799956958020" + " IN IP4 127.0.0.1\r\n"
  193. + "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"
  194. + "m=audio 6022 RTP/AVP 0 4 18\r\n" + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n"
  195. + "a=rtpmap:18 G729A/8000\r\n" + "a=ptime:20\r\n";
  196. createConnection.setRemoteConnectionDescriptor(new ConnectionDescriptor(sdpData));
  197. createConnection.setTransactionHandle(caProvider.getUniqueTransactionHandler());
  198. nbConcurrentInvite.incrementAndGet();
  199. if (logger.isDebugEnabled()) {
  200. logger.debug("Sending CRCX Tx Id = " + createConnection.getTransactionHandle());
  201. }
  202. caProvider.sendMgcpEvents(new JainMgcpEvent[] { createConnection });
  203. } catch (Exception e) {
  204. // TODO Auto-generated catch block
  205. e.printStackTrace();
  206. fail("Unexpected Exception " + e.getMessage());
  207. }
  208. }
  209. class Appdata {
  210. protected TTask ttask;
  211. protected long startTime;
  212. protected long endTime;
  213. private ConnectionIdentifier connectionIdentifier = null;
  214. private boolean receivedCrcxResponse = false;
  215. private boolean receivedRqntResponse = false;
  216. private boolean receivedDlcxResponse = false;
  217. String endpointId = null;
  218. Appdata(String endpointId) {
  219. this.endpointId = endpointId;
  220. ttask = new TTask(this);
  221. timer.schedule(ttask, 20 * 1000 * NDIALOGS / 100);
  222. startTime = System.currentTimeMillis();
  223. }
  224. public void setReceivedCrcxResponse(boolean response) {
  225. if (!receivedRqntResponse && !receivedDlcxResponse) {
  226. this.receivedCrcxResponse = response;
  227. } else {
  228. System.out.println("receivedCrcxResponse after receivedRqntResponse or receivedDlcxResponse");
  229. System.out.println("System falsed " + this.toString());
  230. System.exit(0);
  231. }
  232. }
  233. public void setReceivedRqntResponse(boolean response) {
  234. if (receivedCrcxResponse && !receivedDlcxResponse) {
  235. this.receivedRqntResponse = response;
  236. } else {
  237. System.out.println("receivedRqntResponse after receivedDlcxResponse or before receivedCrcxResponse");
  238. System.out.println("System falsed " + this.toString());
  239. System.exit(0);
  240. }
  241. }
  242. public void setReceivedDlcxResponse(boolean response) {
  243. if (receivedCrcxResponse && receivedRqntResponse) {
  244. this.receivedDlcxResponse = response;
  245. } else {
  246. System.out.println("receivedDlcxResponse before receivedCrcxResponse or receivedDlcxResponse");
  247. System.out.println("System falsed " + this.toString());
  248. System.exit(0);
  249. }
  250. }
  251. public TTask getTtask() {
  252. return ttask;
  253. }
  254. public void setTtask(TTask ttask) {
  255. this.ttask = ttask;
  256. }
  257. public String getEndpointId() {
  258. return endpointId;
  259. }
  260. public void setEndpointId(String endpointId) {
  261. this.endpointId = endpointId;
  262. }
  263. public boolean isReceivedCrcxResponse() {
  264. return receivedCrcxResponse;
  265. }
  266. public boolean isReceivedRqntResponse() {
  267. return receivedRqntResponse;
  268. }
  269. public boolean isReceivedDlcxResponse() {
  270. return receivedDlcxResponse;
  271. }
  272. public void cancelTimer() {
  273. this.ttask.cancel();
  274. endTime = System.currentTimeMillis();
  275. }
  276. public String toString() {
  277. return new StringBuffer("EndpointId = ").append(this.endpointId).append(" receivedCrcxResponse = ").append(
  278. receivedCrcxResponse).append(" receivedRqntResponse= ").append(receivedRqntResponse).append(
  279. " receivedDlcxResponse= ").append(receivedDlcxResponse).toString();
  280. }
  281. public ConnectionIdentifier getConnectionIdentifier() {
  282. return connectionIdentifier;
  283. }
  284. public void setConnectionIdentifier(ConnectionIdentifier connectionIdentifier) {
  285. this.connectionIdentifier = connectionIdentifier;
  286. }
  287. }
  288. class TTask extends TimerTask {
  289. Appdata appdata;
  290. public TTask(Appdata appdata) {
  291. this.appdata = appdata;
  292. }
  293. public void run() {
  294. if (!this.appdata.isReceivedCrcxResponse() || !this.appdata.isReceivedDlcxResponse()
  295. || !this.appdata.isReceivedRqntResponse()) {
  296. System.out.println("Appdata " + appdata.toString());
  297. logger.info("Appdata " + appdata.toString());
  298. System.exit(0);
  299. } else {
  300. this.appdata = null;
  301. }
  302. }
  303. }
  304. public static void main(String args[]) {
  305. int noOfCalls = Integer.parseInt(args[0]);
  306. int noOfConcurrentCalls = Integer.parseInt(args[1]);
  307. System.out.println("Number calls to be completed = " + noOfCalls
  308. + " Number of concurrent calls to be maintained = " + noOfConcurrentCalls);
  309. logger.info("Number calls to be completed = " + noOfCalls + " Number of concurrent calls to be maintained = "
  310. + noOfConcurrentCalls);
  311. NDIALOGS = noOfCalls;
  312. MAXCONCURRENTCRCX = noOfConcurrentCalls;
  313. final CA ca = new CA();
  314. try {
  315. ca.createMgcpStack(ca);
  316. ca.start = System.currentTimeMillis();
  317. while (ca.deleteCount < NDIALOGS) {
  318. while (ca.nbConcurrentInvite.intValue() >= MAXCONCURRENTCRCX) {
  319. System.out.println("nbConcurrentInvite = " + ca.nbConcurrentInvite.intValue()
  320. + " Waiting for max CRCX count to go down!");
  321. logger.info("nbConcurrentInvite = " + ca.nbConcurrentInvite.intValue()
  322. + " Waiting for max CRCX count to go down!");
  323. synchronized (ca) {
  324. try {
  325. ca.wait();
  326. } catch (Exception ex) {
  327. }
  328. }
  329. }
  330. if (ca.deleteCount == 0) {
  331. ca.start = System.currentTimeMillis();
  332. }
  333. // try {
  334. // Thread.sleep(2);
  335. // } catch (InterruptedException e) {
  336. // }
  337. ca.sendCreateConnection();
  338. }
  339. } catch (UnknownHostException e) {
  340. e.printStackTrace();
  341. } catch (CreateProviderException e) {
  342. e.printStackTrace();
  343. } catch (TooManyListenersException e) {
  344. e.printStackTrace();
  345. }
  346. }
  347. }