PageRenderTime 52ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

/servers/jain-sip-ha/jboss-5/src/test/java/org/mobicents/ha/javax/sip/SimpleStatefulProxy.java

http://mobicents.googlecode.com/
Java | 663 lines | 508 code | 51 blank | 104 comment | 70 complexity | 6d6580b023df73c8bee208a1dbeb871b MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, GPL-2.0, CC-BY-SA-3.0, CC0-1.0, Apache-2.0, BSD-3-Clause
  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.ha.javax.sip;
  23. import gov.nist.javax.sip.RequestEventExt;
  24. import gov.nist.javax.sip.ResponseEventExt;
  25. import gov.nist.javax.sip.message.MessageExt;
  26. import gov.nist.javax.sip.message.SIPRequest;
  27. import java.rmi.registry.LocateRegistry;
  28. import java.rmi.registry.Registry;
  29. import java.text.ParseException;
  30. import java.util.ArrayList;
  31. import java.util.Collections;
  32. import java.util.HashSet;
  33. import java.util.Iterator;
  34. import java.util.Properties;
  35. import java.util.Set;
  36. import java.util.Timer;
  37. import java.util.TimerTask;
  38. import javax.sip.ClientTransaction;
  39. import javax.sip.DialogTerminatedEvent;
  40. import javax.sip.IOExceptionEvent;
  41. import javax.sip.InvalidArgumentException;
  42. import javax.sip.ListeningPoint;
  43. import javax.sip.RequestEvent;
  44. import javax.sip.ResponseEvent;
  45. import javax.sip.ServerTransaction;
  46. import javax.sip.SipException;
  47. import javax.sip.SipFactory;
  48. import javax.sip.SipListener;
  49. import javax.sip.SipProvider;
  50. import javax.sip.SipStack;
  51. import javax.sip.TimeoutEvent;
  52. import javax.sip.TransactionTerminatedEvent;
  53. import javax.sip.address.Address;
  54. import javax.sip.address.AddressFactory;
  55. import javax.sip.address.SipURI;
  56. import javax.sip.header.CSeqHeader;
  57. import javax.sip.header.CallIdHeader;
  58. import javax.sip.header.ContactHeader;
  59. import javax.sip.header.ContentLengthHeader;
  60. import javax.sip.header.FromHeader;
  61. import javax.sip.header.HeaderFactory;
  62. import javax.sip.header.RecordRouteHeader;
  63. import javax.sip.header.RouteHeader;
  64. import javax.sip.header.ToHeader;
  65. import javax.sip.header.ViaHeader;
  66. import javax.sip.message.MessageFactory;
  67. import javax.sip.message.Request;
  68. import javax.sip.message.Response;
  69. import org.jboss.cache.CacheException;
  70. import org.jboss.cache.Fqn;
  71. import org.mobicents.ha.javax.sip.cache.ManagedMobicentsSipCache;
  72. import org.mobicents.ha.javax.sip.cache.MobicentsSipCache;
  73. import org.mobicents.tools.sip.balancer.NodeRegisterRMIStub;
  74. import org.mobicents.tools.sip.balancer.SIPNode;
  75. public class SimpleStatefulProxy implements SipListener {
  76. private static final String SIP_BIND_ADDRESS = "javax.sip.IP_ADDRESS";
  77. private static final String SIP_PORT_BIND = "javax.sip.PORT";
  78. private static final String TRANSPORTS_BIND = "javax.sip.TRANSPORT";
  79. private SipFactory sipFactory;
  80. private SipStack sipStack;
  81. private ListeningPoint listeningPoint;
  82. private Properties properties;
  83. private SipProvider sipProvider;
  84. private MessageFactory messageFactory;
  85. private HeaderFactory headerFactory;
  86. private AddressFactory addressFactory;
  87. private ServerTransaction serverTransaction;
  88. private ClientTransaction clientTransaction;
  89. private String currentCtxBranchId;
  90. private Integer currentCtxRemotePort;
  91. int myPort;
  92. String transport;
  93. String ipAddress;
  94. private TimerTask keepaliveTask;
  95. public SimpleStatefulProxy(String stackName, String ipAddress, int port, String transport, ReplicationStrategy replicationStrategy) {
  96. // this.localTag = localTag;
  97. myPort = port;
  98. this.transport = transport;
  99. this.ipAddress = ipAddress;
  100. properties = new Properties();
  101. properties.setProperty("javax.sip.STACK_NAME", stackName);
  102. properties.setProperty(SIP_PORT_BIND, String.valueOf(myPort));
  103. properties.setProperty("javax.sip.OUTBOUND_PROXY", ipAddress + ":" + Integer.toString(5065) + "/" + transport);
  104. // You need 16 for logging traces. 32 for debug + traces.
  105. // Your code will limp at 32 but it is best for debugging.
  106. properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
  107. properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "logs/" +
  108. stackName + "debug.txt");
  109. properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "logs/" +
  110. stackName + "log.xml");
  111. properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off");
  112. properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true");
  113. properties.setProperty("org.mobicents.ha.javax.sip.REPLICATION_STRATEGY", replicationStrategy.toString());
  114. properties.setProperty(ManagedMobicentsSipCache.STANDALONE, "true");
  115. System.setProperty("jgroups.bind_addr", ipAddress);
  116. System.setProperty("jgroups.udp.mcast_addr", "FFFF::232.5.5.5");
  117. System.setProperty("jboss.server.log.threshold", "DEBUG");
  118. System.setProperty("jbosscache.config.validate", "false");
  119. try {
  120. initStack(ipAddress, transport);
  121. } catch (Exception e) {
  122. e.printStackTrace();
  123. }
  124. }
  125. public void initStack(String ipAddress, String transport) throws Exception {
  126. this.sipFactory = SipFactory.getInstance();
  127. this.sipFactory.setPathName("org.mobicents.ha");
  128. //this.sipFactory.setPathName("gov.nist");
  129. this.sipStack = this.sipFactory.createSipStack(properties);
  130. this.sipStack.start();
  131. this.listeningPoint = this.sipStack.createListeningPoint(properties.getProperty(
  132. SIP_BIND_ADDRESS, ipAddress), Integer.valueOf(properties
  133. .getProperty(SIP_PORT_BIND, "5060")), properties.getProperty(
  134. TRANSPORTS_BIND, transport));
  135. this.sipProvider = this.sipStack.createSipProvider(this.listeningPoint);
  136. this.sipProvider.addSipListener(this);
  137. this.headerFactory = sipFactory.createHeaderFactory();
  138. this.messageFactory = sipFactory.createMessageFactory();
  139. this.addressFactory = sipFactory.createAddressFactory();
  140. properties.setProperty(SIP_BIND_ADDRESS, ipAddress);
  141. }
  142. private void storeServerTransactionId(String branchId) {
  143. ((ClusteredSipStack)sipProvider.getSipStack()).getStackLogger().logDebug("Storing transaction Id " + branchId);
  144. try {
  145. ((MobicentsSipCache)((ClusteredSipStack)sipProvider.getSipStack()).getSipCache()).getMobicentsCache().getJBossCache().put(Fqn.fromString("STX_IDS"), "serverTransactionId", branchId);
  146. } catch (CacheException e) {
  147. // TODO Auto-generated catch block
  148. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  149. }
  150. }
  151. private void storeClientTransactionId(String branchId, int port) {
  152. ((ClusteredSipStack)sipProvider.getSipStack()).getStackLogger().logDebug("Storing client Id " + branchId + " and remote port" + port);
  153. currentCtxBranchId = branchId;
  154. currentCtxRemotePort = Integer.valueOf(port);
  155. try {
  156. ((MobicentsSipCache)((ClusteredSipStack)sipProvider.getSipStack()).getSipCache()).getMobicentsCache().getJBossCache().put(Fqn.fromString("CTX_IDS"), "clientTransactionId", branchId);
  157. ((MobicentsSipCache)((ClusteredSipStack)sipProvider.getSipStack()).getSipCache()).getMobicentsCache().getJBossCache().put(Fqn.fromString("CTX_PORT"), "clientTransactionRemotePort", currentCtxRemotePort);
  158. } catch (CacheException e) {
  159. // TODO Auto-generated catch block
  160. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  161. }
  162. }
  163. /**
  164. * @return the outgoingDialog
  165. */
  166. public ServerTransaction getServerTransaction() {
  167. if(serverTransaction != null) {
  168. return serverTransaction;
  169. }
  170. String serverTransactionId = null;
  171. try {
  172. serverTransactionId = (String) ((MobicentsSipCache)((ClusteredSipStack)sipProvider.getSipStack()).getSipCache()).getMobicentsCache().getJBossCache().get(Fqn.fromString("STX_IDS"), "serverTransactionId");
  173. } catch (CacheException e) {
  174. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  175. }
  176. ((ClusteredSipStack)sipStack).getStackLogger().logInfo("server transaction Id " + serverTransactionId);
  177. if(serverTransactionId == null) {
  178. return null;
  179. }
  180. serverTransaction = (ServerTransaction) ((ClusteredSipStack)sipProvider.getSipStack()).findTransaction(serverTransactionId, true);
  181. return serverTransaction;
  182. }
  183. /**
  184. * @return the outgoingDialog
  185. */
  186. public ClientTransaction getClientTransaction() {
  187. if(clientTransaction != null) {
  188. return clientTransaction;
  189. }
  190. String clientTransactionId = null;
  191. try {
  192. clientTransactionId = (String) ((MobicentsSipCache)((ClusteredSipStack)sipProvider.getSipStack()).getSipCache()).getMobicentsCache().getJBossCache().get(Fqn.fromString("CTX_IDS"), "clientTransactionId");
  193. } catch (CacheException e) {
  194. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  195. }
  196. ((ClusteredSipStack)sipStack).getStackLogger().logInfo("client transaction Id " + clientTransactionId);
  197. if(clientTransactionId == null) {
  198. return null;
  199. }
  200. return (ClientTransaction) ((ClusteredSipStack)sipProvider.getSipStack()).findTransaction(clientTransactionId, false);
  201. }
  202. /**
  203. * @return the outgoingDialog
  204. */
  205. public String getClientTransactionId() {
  206. String clientTransactionId = currentCtxBranchId;
  207. if(clientTransactionId == null) {
  208. try {
  209. clientTransactionId = (String) ((MobicentsSipCache)((ClusteredSipStack)sipProvider.getSipStack()).getSipCache()).getMobicentsCache().getJBossCache().get(Fqn.fromString("CTX_IDS"), "clientTransactionId");
  210. } catch (CacheException e) {
  211. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  212. }
  213. }
  214. return clientTransactionId;
  215. }
  216. /**
  217. * @return the outgoingDialog
  218. */
  219. public int getClientTransactionPort() {
  220. Integer clientTransactionRemotePort = currentCtxRemotePort;
  221. if(clientTransactionRemotePort == null) {
  222. try {
  223. clientTransactionRemotePort = (Integer) ((MobicentsSipCache)((ClusteredSipStack)sipProvider.getSipStack()).getSipCache()).getMobicentsCache().getJBossCache().get(Fqn.fromString("CTX_PORT"), "clientTransactionRemotePort");
  224. } catch (CacheException e) {
  225. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  226. }
  227. }
  228. return clientTransactionRemotePort.intValue();
  229. }
  230. public void processInvite(RequestEvent requestEvent) {
  231. //System.out.println("Got invite: "+requestEvent.getRequest());
  232. try {
  233. serverTransaction = requestEvent.getServerTransaction();
  234. if (serverTransaction == null) {
  235. try {
  236. serverTransaction = sipProvider.getNewServerTransaction(requestEvent.getRequest());
  237. }
  238. catch (Exception e) {
  239. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  240. return;
  241. }
  242. }
  243. storeServerTransactionId(serverTransaction.getBranchId());
  244. serverTransaction.sendResponse(messageFactory.createResponse(100, requestEvent.getRequest()));
  245. int peerPort = 5070;
  246. if(((MessageExt)requestEvent.getRequest()).getToHeader().getTag() != null) {
  247. peerPort = 5050;
  248. ((MessageExt)requestEvent.getRequest()).removeLast(RouteHeader.NAME);
  249. }
  250. forwardInvite(peerPort);
  251. } catch (Exception ex) {
  252. ex.printStackTrace();
  253. }
  254. }
  255. /**
  256. * @param incomingDialog2
  257. * @return
  258. * @throws SipException
  259. * @throws InvalidArgumentException
  260. * @throws ParseException
  261. */
  262. private void forwardInvite(int peerPort) throws SipException, ParseException, InvalidArgumentException {
  263. Request request = createRequest(getServerTransaction().getRequest(), peerPort);
  264. Address address = null;
  265. try {
  266. address = addressFactory.createAddress("sip:" + ipAddress + ":" + myPort);
  267. } catch (ParseException e) {
  268. e.printStackTrace();
  269. throw new SipException(e.getMessage());
  270. }
  271. RecordRouteHeader recordRouteHeader = headerFactory.createRecordRouteHeader(address);
  272. request.addFirst(recordRouteHeader);
  273. RouteHeader routeHeader = (RouteHeader) request.getHeader(RouteHeader.NAME);
  274. if(routeHeader != null && (((SipURI)routeHeader.getAddress().getURI()).getPort() == 5080 || ((SipURI)routeHeader.getAddress().getURI()).getPort() == 5081)) {
  275. request.removeFirst(RouteHeader.NAME);
  276. }
  277. request.addHeader(headerFactory.createViaHeader(ipAddress, myPort, transport, null));
  278. ClientTransaction ct = sipProvider.getNewClientTransaction(request);
  279. clientTransaction = ct;
  280. clientTransaction.sendRequest();
  281. storeClientTransactionId(clientTransaction.getBranchId(), peerPort);
  282. }
  283. @SuppressWarnings("unchecked")
  284. private Request createRequest(Request origRequest, int peerPort) throws SipException {
  285. final SIPRequest request = (SIPRequest) origRequest.clone();
  286. ((SipURI)request.getRequestURI()).setPort(peerPort);
  287. return request;
  288. }
  289. public void processAck(RequestEvent requestEvent) {
  290. int remotePort = ((RequestEventExt)requestEvent).getRemotePort() ;
  291. if(ListeningPoint.TCP.equalsIgnoreCase(transport)) {
  292. remotePort = ((MessageExt)requestEvent.getRequest()).getTopmostViaHeader().getPort();
  293. }
  294. ((ClusteredSipStack)sipStack).getStackLogger().logDebug("remotePort = " + remotePort);
  295. try {
  296. final Request ack = (Request) requestEvent.getRequest().clone();
  297. String branchId = getClientTransactionId();
  298. ack.addHeader(headerFactory.createViaHeader(ipAddress, myPort, transport, branchId));
  299. ((SipURI)ack.getRequestURI()).setPort(getClientTransactionPort());
  300. ack.removeLast(RouteHeader.NAME);
  301. RouteHeader routeHeader = (RouteHeader) ack.getHeader(RouteHeader.NAME);
  302. if(routeHeader != null && (((SipURI)routeHeader.getAddress().getURI()).getPort() == 5080 || ((SipURI)routeHeader.getAddress().getURI()).getPort() == 5081)) {
  303. ack.removeFirst(RouteHeader.NAME);
  304. }
  305. sipProvider.sendRequest(ack);
  306. } catch (Exception e) {
  307. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  308. }
  309. }
  310. public void processBye(RequestEvent requestEvent) {
  311. try {
  312. serverTransaction = requestEvent.getServerTransaction();
  313. if (serverTransaction == null) {
  314. try {
  315. serverTransaction = sipProvider.getNewServerTransaction(requestEvent.getRequest());
  316. }
  317. catch (Exception e) {
  318. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  319. return;
  320. }
  321. }
  322. int remotePort = ((RequestEventExt)requestEvent).getRemotePort() ;
  323. if(ListeningPoint.TCP.equalsIgnoreCase(transport)) {
  324. remotePort = ((MessageExt)requestEvent.getRequest()).getTopmostViaHeader().getPort();
  325. }
  326. ((ClusteredSipStack)sipStack).getStackLogger().logDebug("remotePort = " + remotePort);
  327. final Request request = (Request) requestEvent.getRequest().clone();
  328. ((SipURI)request.getRequestURI()).setPort(5070);
  329. request.removeLast(RouteHeader.NAME);
  330. RouteHeader routeHeader = (RouteHeader) request.getHeader(RouteHeader.NAME);
  331. if(routeHeader != null && (((SipURI)routeHeader.getAddress().getURI()).getPort() == 5080 || ((SipURI)routeHeader.getAddress().getURI()).getPort() == 5081)) {
  332. request.removeFirst(RouteHeader.NAME);
  333. }
  334. request.addHeader(headerFactory.createViaHeader(ipAddress, myPort, transport, null));
  335. final ClientTransaction ct = sipProvider.getNewClientTransaction(request);
  336. ct.sendRequest();
  337. }
  338. catch (Exception e) {
  339. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  340. }
  341. }
  342. // public void processSubscribe(RequestEvent requestEvent) {
  343. // try {
  344. // Response response = messageFactory.createResponse(200, requestEvent.getRequest());
  345. // response.addHeader(headerFactory.createHeader(ExpiresHeader.NAME, "3600"));
  346. // requestEvent.getServerTransaction().sendResponse(response);
  347. // Dialog dialog = getOutgoingDialog();
  348. // Request request = dialog.createRequest(Request.SUBSCRIBE);
  349. // ((SipURI)request.getRequestURI()).setPort(5070);
  350. // final ClientTransaction ct = sipProvider.getNewClientTransaction(request);
  351. // dialog.sendRequest(ct);
  352. // }
  353. // catch (Exception e) {
  354. // ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  355. // }
  356. // }
  357. //
  358. // public void processNotify(RequestEvent requestEvent) {
  359. // try {
  360. // requestEvent.getServerTransaction().sendResponse(messageFactory.createResponse(200, requestEvent.getRequest()));
  361. // Dialog dialog = getIncomingDialog();
  362. // Request request = dialog.createRequest(Request.NOTIFY);
  363. // request.addHeader(headerFactory.createHeader(SubscriptionStateHeader.NAME, SubscriptionStateHeader.ACTIVE));
  364. // request.addHeader(headerFactory.createHeader(EventHeader.NAME, "presence"));
  365. // ((SipURI)request.getRequestURI()).setUser(null);
  366. //// ((SipURI)request.getRequestURI()).setHost(IP_ADDRESS);
  367. // ((SipURI)request.getRequestURI()).setPort(5050);
  368. // final ClientTransaction ct = sipProvider.getNewClientTransaction(request);
  369. // dialog.sendRequest(ct);
  370. // }
  371. // catch (Exception e) {
  372. // ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  373. // }
  374. // }
  375. public void process180(ResponseEvent responseEvent) {
  376. try {
  377. forwardResponse(responseEvent.getResponse());
  378. }
  379. catch (Exception e) {
  380. ((SipStackImpl)sipStack).getStackLogger().logError("unexpected exception", e);
  381. }
  382. }
  383. /**
  384. * @param responseEvent
  385. * @throws InvalidArgumentException
  386. */
  387. @SuppressWarnings("unchecked")
  388. private void forwardResponse(Response receivedResponse) throws SipException, InvalidArgumentException {
  389. System.out.println("Forwarding " + receivedResponse);
  390. final ServerTransaction origServerTransaction = this.getServerTransaction();
  391. Response forgedResponse = (Response) receivedResponse.clone();
  392. forgedResponse.removeFirst(ViaHeader.NAME);
  393. origServerTransaction.sendResponse(forgedResponse);
  394. }
  395. public void process200(ResponseEvent responseEvent) {
  396. try {
  397. boolean isRetransmission = ((ResponseEventExt)responseEvent).isRetransmission();
  398. ClientTransaction clientTransaction = ((ResponseEventExt)responseEvent).getClientTransaction();
  399. ((ClusteredSipStack)sipStack).getStackLogger().logDebug("clientTransaction = " + clientTransaction + ", isRetransmission " + isRetransmission);
  400. final CSeqHeader cSeqHeader = (CSeqHeader) responseEvent.getResponse().getHeader(CSeqHeader.NAME);
  401. if (cSeqHeader.getMethod().equals(Request.INVITE)) {
  402. processInvite200(responseEvent,cSeqHeader);
  403. }
  404. else if (cSeqHeader.getMethod().equals(Request.BYE) || cSeqHeader.getMethod().equals(Request.SUBSCRIBE) || cSeqHeader.getMethod().equals(Request.NOTIFY)) {
  405. processBye200(responseEvent);
  406. }
  407. else {
  408. System.err.println("Unexpected response: "+responseEvent.getResponse());
  409. }
  410. } catch (Exception ex) {
  411. ex.printStackTrace();
  412. }
  413. }
  414. /**
  415. * @param responseEvent
  416. * @throws SipException
  417. * @throws InvalidArgumentException
  418. */
  419. private void processInvite200(ResponseEvent responseEvent,CSeqHeader cseq) throws InvalidArgumentException, SipException {
  420. // lets ack it ourselves to avoid UAS retransmissions due to
  421. // forwarding of this response and further UAC Ack
  422. // note that the app does not handles UAC ACKs
  423. // String outgoingDialogId = responseEvent.getDialog().getDialogId();
  424. int remotePort = ((ResponseEventExt)responseEvent).getRemotePort() ;
  425. if(ListeningPoint.TCP.equalsIgnoreCase(transport)) {
  426. remotePort = ((MessageExt)responseEvent.getResponse()).getTopmostViaHeader().getPort();
  427. }
  428. ((ClusteredSipStack)sipStack).getStackLogger().logDebug("remotePort = " + remotePort);
  429. // if(remotePort == 5065 || remotePort == 5081) {
  430. // storeOutgoingDialogId(outgoingDialogId);
  431. // }
  432. // if(myPort == 5080 && getOutgoingDialogId() == null) {
  433. // storeOutgoingDialogId(outgoingDialogId);
  434. // }
  435. forwardResponse(responseEvent.getResponse());
  436. }
  437. /**
  438. * @param responseEvent
  439. */
  440. private void processBye200(ResponseEvent responseEvent) {
  441. try {
  442. forwardResponse(responseEvent.getResponse());
  443. } catch (SipException e) {
  444. e.printStackTrace();
  445. } catch (InvalidArgumentException e) {
  446. e.printStackTrace();
  447. }
  448. }
  449. private static Set<String> HEADERS_TO_OMMIT_ON_RESPONSE_COPY;
  450. private static Set<String> getHeadersToOmmitOnResponseCopy() {
  451. if (HEADERS_TO_OMMIT_ON_RESPONSE_COPY == null) {
  452. final Set<String> set = new HashSet<String>();
  453. set.add(RouteHeader.NAME);
  454. set.add(RecordRouteHeader.NAME);
  455. set.add(ViaHeader.NAME);
  456. set.add(CallIdHeader.NAME);
  457. set.add(CSeqHeader.NAME);
  458. set.add(ContactHeader.NAME);
  459. set.add(FromHeader.NAME);
  460. set.add(ToHeader.NAME);
  461. set.add(ContentLengthHeader.NAME);
  462. HEADERS_TO_OMMIT_ON_RESPONSE_COPY = Collections.unmodifiableSet(set);
  463. }
  464. return HEADERS_TO_OMMIT_ON_RESPONSE_COPY;
  465. }
  466. public void checkState() {
  467. // TODO Auto-generated method stub
  468. }
  469. public void pingBalancer() {
  470. final SIPNode appServerNode = new SIPNode(sipStack.getStackName(), properties.getProperty(SIP_BIND_ADDRESS));
  471. if(ListeningPoint.UDP.equalsIgnoreCase(transport)) {
  472. appServerNode.getProperties().put("udpPort", Integer.parseInt(properties.getProperty(SIP_PORT_BIND)));
  473. } else {
  474. appServerNode.getProperties().put("tcpPort", Integer.parseInt(properties.getProperty(SIP_PORT_BIND)));
  475. }
  476. keepaliveTask = new TimerTask() {
  477. @Override
  478. public void run() {
  479. ArrayList<SIPNode> nodes = new ArrayList<SIPNode>();
  480. nodes.add(appServerNode);
  481. sendKeepAliveToBalancers(nodes);
  482. }
  483. };
  484. new Timer().schedule(keepaliveTask, 0, 1000);
  485. }
  486. private void sendKeepAliveToBalancers(ArrayList<SIPNode> info) {
  487. if(true) {
  488. Thread.currentThread().setContextClassLoader(NodeRegisterRMIStub.class.getClassLoader());
  489. try {
  490. Registry registry = LocateRegistry.getRegistry(properties.getProperty(SIP_BIND_ADDRESS), 2000);
  491. NodeRegisterRMIStub reg=(NodeRegisterRMIStub) registry.lookup("SIPBalancer");
  492. reg.handlePing(info);
  493. } catch (Exception e) {
  494. if(sipStack != null) {
  495. ((ClusteredSipStack)sipStack).getStackLogger().logError("couldn't contact the LB, cancelling the keepalive task");
  496. }
  497. keepaliveTask.cancel();
  498. }
  499. }
  500. }
  501. public void stopPingBalancer() {
  502. keepaliveTask.cancel();
  503. Thread.currentThread().setContextClassLoader(NodeRegisterRMIStub.class.getClassLoader());
  504. try {
  505. Registry registry = LocateRegistry.getRegistry(properties.getProperty(SIP_BIND_ADDRESS), 2000);
  506. NodeRegisterRMIStub reg=(NodeRegisterRMIStub) registry.lookup("SIPBalancer");
  507. final SIPNode appServerNode = new SIPNode(sipStack.getStackName(), properties.getProperty(SIP_BIND_ADDRESS));
  508. if(ListeningPoint.UDP.equalsIgnoreCase(transport)) {
  509. appServerNode.getProperties().put("udpPort", Integer.parseInt(properties.getProperty(SIP_PORT_BIND)));
  510. } else {
  511. appServerNode.getProperties().put("tcpPort", Integer.parseInt(properties.getProperty(SIP_PORT_BIND)));
  512. }
  513. ArrayList<SIPNode> nodes = new ArrayList<SIPNode>();
  514. nodes.add(appServerNode);
  515. reg.forceRemoval(nodes);
  516. } catch (Exception e) {
  517. }
  518. }
  519. public void stop() {
  520. stop(true);
  521. }
  522. public void stop(boolean stopSipStack) {
  523. Iterator<SipProvider> sipProviderIterator = sipStack.getSipProviders();
  524. try{
  525. while (sipProviderIterator.hasNext()) {
  526. SipProvider sipProvider = sipProviderIterator.next();
  527. if(!ListeningPoint.TCP.equalsIgnoreCase(transport)) {
  528. ListeningPoint[] listeningPoints = sipProvider.getListeningPoints();
  529. for (ListeningPoint listeningPoint : listeningPoints) {
  530. sipProvider.removeListeningPoint(listeningPoint);
  531. sipStack.deleteListeningPoint(listeningPoint);
  532. listeningPoints = sipProvider.getListeningPoints();
  533. }
  534. }
  535. sipProvider.removeSipListener(this);
  536. sipStack.deleteSipProvider(sipProvider);
  537. sipProviderIterator = sipStack.getSipProviders();
  538. }
  539. } catch (Exception e) {
  540. throw new IllegalStateException("Cant remove the listening points or sip providers", e);
  541. }
  542. listeningPoint = null;
  543. sipProvider = null;
  544. sipFactory.resetFactory();
  545. serverTransaction = null;
  546. clientTransaction = null;
  547. currentCtxBranchId = null;
  548. currentCtxRemotePort = null;
  549. if(stopSipStack){
  550. sipStack.stop();
  551. sipStack = null;
  552. headerFactory = null;
  553. messageFactory = null;
  554. sipFactory = null;
  555. properties = null;
  556. }
  557. }
  558. public void processDialogTerminated(
  559. DialogTerminatedEvent dialogTerminatedEvent) {}
  560. public void processIOException(IOExceptionEvent exceptionEvent) {}
  561. public void processRequest(RequestEvent requestEvent) {
  562. if (requestEvent.getRequest().getMethod().equals(Request.INVITE)) {
  563. processInvite(requestEvent);
  564. }
  565. else if (requestEvent.getRequest().getMethod().equals(Request.BYE)) {
  566. processBye(requestEvent);
  567. }
  568. else if (requestEvent.getRequest().getMethod().equals(Request.ACK)) {
  569. processAck(requestEvent);
  570. }
  571. else {
  572. ((ClusteredSipStack)sipStack).getStackLogger().logError("Received unexpected sip request: "+requestEvent.getRequest());
  573. }
  574. }
  575. public void processResponse(ResponseEvent responseEvent) {
  576. if(responseEvent.getClientTransaction() != null) {
  577. System.out.println("transaction is " + responseEvent.getClientTransaction().getBranchId() + " for response " +responseEvent.getResponse() );
  578. } else {
  579. System.out.println("null tx for response " +responseEvent.getResponse() );
  580. }
  581. switch (responseEvent.getResponse().getStatusCode()) {
  582. case 100:
  583. // ignore
  584. break;
  585. case 180:
  586. process180(responseEvent);
  587. break;
  588. case 200:
  589. process200(responseEvent);
  590. break;
  591. case 202:
  592. process200(responseEvent);
  593. break;
  594. default:
  595. System.err.println("Received unexpected sip response: "+responseEvent.getResponse());
  596. break;
  597. }
  598. }
  599. public void processTimeout(TimeoutEvent timeoutEvent) {}
  600. public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {}
  601. public boolean checkTransactionsRemoved() {
  602. System.out.println("client transaction table size " + ((SipStackImpl)sipStack).getClientTransactionTableSize());
  603. if(((SipStackImpl)sipStack).getClientTransactionTableSize() > 0) {
  604. return false;
  605. }
  606. System.out.println("server transaction table size " + ((SipStackImpl)sipStack).getServerTransactionTableSize());
  607. if(((SipStackImpl)sipStack).getServerTransactionTableSize() > 0) {
  608. return false;
  609. }
  610. return true;
  611. }
  612. }