PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/servers/jain-sip-ha/core/src/main/java/org/mobicents/ha/javax/sip/LoadBalancerHeartBeatingServiceImpl.java

http://mobicents.googlecode.com/
Java | 659 lines | 465 code | 83 blank | 111 comment | 88 complexity | 26ff411c68cf0a6b8cffd97a845af6c5 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.core.CommonLogger;
  24. import gov.nist.core.StackLogger;
  25. import java.io.IOException;
  26. import java.net.InetAddress;
  27. import java.net.NetworkInterface;
  28. import java.net.SocketException;
  29. import java.net.UnknownHostException;
  30. import java.rmi.registry.LocateRegistry;
  31. import java.rmi.registry.Registry;
  32. import java.util.ArrayList;
  33. import java.util.Enumeration;
  34. import java.util.HashSet;
  35. import java.util.Iterator;
  36. import java.util.List;
  37. import java.util.Map;
  38. import java.util.Properties;
  39. import java.util.Set;
  40. import java.util.Timer;
  41. import java.util.TimerTask;
  42. import java.util.concurrent.ConcurrentHashMap;
  43. import java.util.concurrent.CopyOnWriteArraySet;
  44. import javax.management.ObjectName;
  45. import javax.sip.ListeningPoint;
  46. import org.mobicents.ha.javax.sip.util.Inet6Util;
  47. import org.mobicents.tools.sip.balancer.NodeRegisterRMIStub;
  48. import org.mobicents.tools.sip.balancer.SIPNode;
  49. /**
  50. * <p>implementation of the <code>LoadBalancerHeartBeatingService</code> interface.</p>
  51. *
  52. * <p>
  53. * It sends heartbeats and health information to the sip balancers configured through the stack property org.mobicents.ha.javax.sip.BALANCERS
  54. * </p>
  55. *
  56. * @author <A HREF="mailto:jean.deruelle@gmail.com">Jean Deruelle</A>
  57. *
  58. */
  59. public class LoadBalancerHeartBeatingServiceImpl implements LoadBalancerHeartBeatingService, LoadBalancerHeartBeatingServiceImplMBean {
  60. private static StackLogger logger = CommonLogger.getLogger(LoadBalancerHeartBeatingServiceImpl.class);
  61. public static String LB_HB_SERVICE_MBEAN_NAME = "org.mobicents.jain.sip:type=load-balancer-heartbeat-service,name=";
  62. public static final int DEFAULT_RMI_PORT = 2000;
  63. public static final String BALANCER_SIP_PORT_CHAR_SEPARATOR = ":";
  64. public static final String BALANCERS_CHAR_SEPARATOR = ";";
  65. public static final int DEFAULT_LB_SIP_PORT = 5065;
  66. ClusteredSipStack sipStack = null;
  67. //the logger
  68. //the balancers to send heartbeat to and our health info
  69. protected String balancers;
  70. //the jvmRoute for this node
  71. protected String jvmRoute;
  72. //the balancers names to send heartbeat to and our health info
  73. protected Map<String, SipLoadBalancer> register = new ConcurrentHashMap<String, SipLoadBalancer>();
  74. //heartbeat interval, can be modified through JMX
  75. protected long heartBeatInterval = 5000;
  76. protected Timer heartBeatTimer = new Timer();
  77. protected TimerTask hearBeatTaskToRun = null;
  78. protected List<String> cachedAnyLocalAddresses = new ArrayList<String>();
  79. protected boolean started = false;
  80. protected Set<LoadBalancerHeartBeatingListener> loadBalancerHeartBeatingListeners;
  81. ObjectName oname = null;
  82. public LoadBalancerHeartBeatingServiceImpl() {
  83. loadBalancerHeartBeatingListeners = new CopyOnWriteArraySet<LoadBalancerHeartBeatingListener>();
  84. }
  85. public void init(ClusteredSipStack clusteredSipStack,
  86. Properties stackProperties) {
  87. sipStack = clusteredSipStack;
  88. balancers = stackProperties.getProperty(BALANCERS);
  89. heartBeatInterval = Integer.parseInt(stackProperties.getProperty(HEARTBEAT_INTERVAL, "5000"));
  90. }
  91. public void stopBalancer() {
  92. stop();
  93. }
  94. public void start() {
  95. Runtime.getRuntime().addShutdownHook(new Thread() {
  96. public void run() {
  97. stopBalancer();
  98. logger.logInfo("Shutting down the Load Balancer Link");}
  99. });
  100. if (!started) {
  101. if (balancers != null && balancers.length() > 0) {
  102. String[] balancerDescriptions = balancers.split(BALANCERS_CHAR_SEPARATOR);
  103. for (String balancerDescription : balancerDescriptions) {
  104. String balancerAddress = balancerDescription;
  105. int sipPort = DEFAULT_LB_SIP_PORT;
  106. int rmiPort = DEFAULT_RMI_PORT;
  107. if(balancerDescription.indexOf(BALANCER_SIP_PORT_CHAR_SEPARATOR) != -1) {
  108. String[] balancerDescriptionSplitted = balancerDescription.split(BALANCER_SIP_PORT_CHAR_SEPARATOR);
  109. balancerAddress = balancerDescriptionSplitted[0];
  110. try {
  111. sipPort = Integer.parseInt(balancerDescriptionSplitted[1]);
  112. if(balancerDescriptionSplitted.length>2) {
  113. rmiPort = Integer.parseInt(balancerDescriptionSplitted[2]);
  114. }
  115. } catch (NumberFormatException e) {
  116. logger.logError("Impossible to parse the following sip balancer port " + balancerDescriptionSplitted[1], e);
  117. }
  118. }
  119. if(Inet6Util.isValidIP6Address(balancerAddress) || Inet6Util.isValidIPV4Address(balancerAddress)) {
  120. try {
  121. this.addBalancer(InetAddress.getByName(balancerAddress).getHostAddress(), sipPort, rmiPort);
  122. } catch (UnknownHostException e) {
  123. logger.logError("Impossible to parse the following sip balancer address " + balancerAddress, e);
  124. }
  125. } else {
  126. this.addBalancer(balancerAddress, sipPort, 0, rmiPort);
  127. }
  128. }
  129. }
  130. started = true;
  131. }
  132. this.hearBeatTaskToRun = new BalancerPingTimerTask();
  133. // Delay the start with 2 seconds so nodes joining under load are really ready to serve requests
  134. // Otherwise one of the listeneing points comes a bit later and results in errors.
  135. this.heartBeatTimer.scheduleAtFixedRate(this.hearBeatTaskToRun, 2000,
  136. this.heartBeatInterval);
  137. if(logger.isLoggingEnabled(StackLogger.TRACE_DEBUG)) {
  138. logger.logDebug("Created and scheduled tasks for sending heartbeats to the sip balancer.");
  139. }
  140. registerMBean();
  141. if(logger.isLoggingEnabled(StackLogger.TRACE_DEBUG)) {
  142. logger.logDebug("Load Balancer Heart Beating Service has been started");
  143. }
  144. }
  145. public void stop() {
  146. // Force removal from load balancer upon shutdown
  147. // added for Issue 308 (http://code.google.com/p/mobicents/issues/detail?id=308)
  148. ArrayList<SIPNode> info = getConnectorsAsSIPNode();
  149. removeNodesFromBalancers(info);
  150. //cleaning
  151. // balancerNames.clear();
  152. register.clear();
  153. if(hearBeatTaskToRun != null) {
  154. this.hearBeatTaskToRun.cancel();
  155. }
  156. this.hearBeatTaskToRun = null;
  157. loadBalancerHeartBeatingListeners.clear();
  158. started = false;
  159. unRegisterMBean();
  160. if(logger.isLoggingEnabled(StackLogger.TRACE_DEBUG)) {
  161. logger.logDebug("Load Balancer Heart Beating Service has been stopped");
  162. }
  163. }
  164. protected void registerMBean() {
  165. String mBeanName = LB_HB_SERVICE_MBEAN_NAME + sipStack.getStackName();
  166. try {
  167. oname = new ObjectName(mBeanName);
  168. if (sipStack.getMBeanServer() != null && !sipStack.getMBeanServer().isRegistered(oname)) {
  169. sipStack.getMBeanServer().registerMBean(this, oname);
  170. }
  171. } catch (Exception e) {
  172. logger.logError("Could not register the Load Balancer Service as an MBean under the following name " + mBeanName, e);
  173. }
  174. }
  175. protected void unRegisterMBean() {
  176. String mBeanName = LB_HB_SERVICE_MBEAN_NAME + sipStack.getStackName();
  177. try {
  178. if (oname != null && sipStack.getMBeanServer() != null && sipStack.getMBeanServer().isRegistered(oname)) {
  179. sipStack.getMBeanServer().unregisterMBean(oname);
  180. }
  181. } catch (Exception e) {
  182. logger.logError("Could not unregister the stack as an MBean under the following name" + mBeanName);
  183. }
  184. }
  185. /**
  186. * {@inheritDoc}
  187. */
  188. public long getHeartBeatInterval() {
  189. return heartBeatInterval;
  190. }
  191. /**
  192. * {@inheritDoc}
  193. */
  194. public void setHeartBeatInterval(long heartBeatInterval) {
  195. if (heartBeatInterval < 100)
  196. return;
  197. if(logger.isLoggingEnabled(StackLogger.TRACE_DEBUG)) {
  198. logger.logDebug("Setting HeartBeatInterval from " + this.heartBeatInterval + " to " + heartBeatInterval);
  199. }
  200. this.heartBeatInterval = heartBeatInterval;
  201. this.hearBeatTaskToRun.cancel();
  202. this.hearBeatTaskToRun = new BalancerPingTimerTask();
  203. this.heartBeatTimer.scheduleAtFixedRate(this.hearBeatTaskToRun, 0,
  204. this.heartBeatInterval);
  205. }
  206. /**
  207. *
  208. * @param hostName
  209. * @param index
  210. * @return
  211. */
  212. private InetAddress fetchHostAddress(String hostName, int index) {
  213. if (hostName == null)
  214. throw new NullPointerException("Host name cant be null!!!");
  215. InetAddress[] hostAddr = null;
  216. try {
  217. hostAddr = InetAddress.getAllByName(hostName);
  218. } catch (UnknownHostException uhe) {
  219. throw new IllegalArgumentException(
  220. "HostName is not a valid host name or it doesnt exists in DNS",
  221. uhe);
  222. }
  223. if (index < 0 || index >= hostAddr.length) {
  224. throw new IllegalArgumentException(
  225. "Index in host address array is wrong, it should be [0]<x<["
  226. + hostAddr.length + "] and it is [" + index + "]");
  227. }
  228. InetAddress address = hostAddr[index];
  229. return address;
  230. }
  231. /**
  232. * {@inheritDoc}
  233. */
  234. public String[] getBalancers() {
  235. return this.register.keySet().toArray(new String[register.keySet().size()]);
  236. }
  237. /**
  238. * {@inheritDoc}
  239. */
  240. public boolean addBalancer(String addr, int sipPort, int rmiPort) {
  241. if (addr == null)
  242. throw new NullPointerException("addr cant be null!!!");
  243. InetAddress address = null;
  244. try {
  245. address = InetAddress.getByName(addr);
  246. } catch (UnknownHostException e) {
  247. throw new IllegalArgumentException(
  248. "Something wrong with host creation.", e);
  249. }
  250. String balancerName = address.getCanonicalHostName() + ":" + rmiPort;
  251. if (register.get(balancerName) != null) {
  252. logger.logInfo("Sip balancer " + balancerName + " already present, not added");
  253. return false;
  254. }
  255. SipLoadBalancer sipLoadBalancer = new SipLoadBalancer(this, address, sipPort, rmiPort);
  256. register.put(balancerName, sipLoadBalancer);
  257. // notify the listeners
  258. for (LoadBalancerHeartBeatingListener loadBalancerHeartBeatingListener : loadBalancerHeartBeatingListeners) {
  259. loadBalancerHeartBeatingListener.loadBalancerAdded(sipLoadBalancer);
  260. }
  261. if(logger.isLoggingEnabled(StackLogger.TRACE_DEBUG)) {
  262. logger.logDebug("following balancer name : " + balancerName +"/address:"+ addr + " added");
  263. }
  264. return true;
  265. }
  266. /**
  267. * {@inheritDoc}
  268. */
  269. public boolean addBalancer(String hostName, int sipPort, int index, int rmiPort) {
  270. return this.addBalancer(fetchHostAddress(hostName, index)
  271. .getHostAddress(), sipPort, rmiPort);
  272. }
  273. /**
  274. * {@inheritDoc}
  275. */
  276. public boolean removeBalancer(String addr, int sipPort, int rmiPort) {
  277. if (addr == null)
  278. throw new NullPointerException("addr cant be null!!!");
  279. InetAddress address = null;
  280. try {
  281. address = InetAddress.getByName(addr);
  282. } catch (UnknownHostException e) {
  283. throw new IllegalArgumentException(
  284. "Something wrong with host creation.", e);
  285. }
  286. SipLoadBalancer sipLoadBalancer = new SipLoadBalancer(this, address, sipPort, rmiPort);
  287. String keyToRemove = null;
  288. Iterator<String> keyIterator = register.keySet().iterator();
  289. while (keyIterator.hasNext() && keyToRemove ==null) {
  290. String key = keyIterator.next();
  291. if(register.get(key).equals(sipLoadBalancer)) {
  292. keyToRemove = key;
  293. }
  294. }
  295. if(keyToRemove !=null ) {
  296. register.remove(keyToRemove);
  297. // notify the listeners
  298. for (LoadBalancerHeartBeatingListener loadBalancerHeartBeatingListener : loadBalancerHeartBeatingListeners) {
  299. loadBalancerHeartBeatingListener.loadBalancerRemoved(sipLoadBalancer);
  300. }
  301. if(logger.isLoggingEnabled(StackLogger.TRACE_DEBUG)) {
  302. logger.logDebug("following balancer name : " + keyToRemove +"/address:"+ addr + " removed");
  303. }
  304. return true;
  305. }
  306. return false;
  307. }
  308. /**
  309. * {@inheritDoc}
  310. */
  311. public boolean removeBalancer(String hostName, int sipPort, int index, int rmiPort) {
  312. InetAddress[] hostAddr = null;
  313. try {
  314. hostAddr = InetAddress.getAllByName(hostName);
  315. } catch (UnknownHostException uhe) {
  316. throw new IllegalArgumentException(
  317. "HostName is not a valid host name or it doesnt exists in DNS",
  318. uhe);
  319. }
  320. if (index < 0 || index >= hostAddr.length) {
  321. throw new IllegalArgumentException(
  322. "Index in host address array is wrong, it should be [0]<x<["
  323. + hostAddr.length + "] and it is [" + index + "]");
  324. }
  325. InetAddress address = hostAddr[index];
  326. return this.removeBalancer(address.getHostAddress(), sipPort, rmiPort);
  327. }
  328. protected ArrayList<SIPNode> getConnectorsAsSIPNode() {
  329. ArrayList<SIPNode> info = new ArrayList<SIPNode>();
  330. Integer sipTcpPort = null;
  331. Integer sipUdpPort = null;
  332. String address = null;
  333. String hostName = null;
  334. // Gathering info about server' sip listening points
  335. Iterator<ListeningPoint> listeningPointIterator = sipStack.getListeningPoints();
  336. while (listeningPointIterator.hasNext()) {
  337. ListeningPoint listeningPoint = listeningPointIterator.next();
  338. address = listeningPoint.getIPAddress();
  339. // From Vladimir: for some reason I get "localhost" here instead of IP and this confiuses the LB
  340. if(address.equals("localhost")) address = "127.0.0.1";
  341. int port = listeningPoint.getPort();
  342. String transport = listeningPoint.getTransport();
  343. if(transport.equalsIgnoreCase("tcp")) {
  344. sipTcpPort = port;
  345. } else if(transport.equals("udp")) {
  346. sipUdpPort = port;
  347. }
  348. try {
  349. InetAddress[] aArray = InetAddress
  350. .getAllByName(address);
  351. if (aArray != null && aArray.length > 0) {
  352. // Damn it, which one we should pick?
  353. hostName = aArray[0].getCanonicalHostName();
  354. }
  355. } catch (UnknownHostException e) {
  356. logger.logError("An exception occurred while trying to retrieve the hostname of a sip connector", e);
  357. }
  358. }
  359. List<String> ipAddresses = new ArrayList<String>();
  360. boolean isAnyLocalAddress = false;
  361. try {
  362. isAnyLocalAddress = InetAddress.getByName(address).isAnyLocalAddress();
  363. } catch (UnknownHostException e) {
  364. logger.logWarning("Unable to enumerate mapped interfaces. Binding to 0.0.0.0 may not work.");
  365. isAnyLocalAddress = false;
  366. }
  367. if(isAnyLocalAddress) {
  368. if(cachedAnyLocalAddresses.isEmpty()) {
  369. try{
  370. Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
  371. while(networkInterfaces.hasMoreElements()) {
  372. NetworkInterface networkInterface = networkInterfaces.nextElement();
  373. Enumeration<InetAddress> bindings = networkInterface.getInetAddresses();
  374. while(bindings.hasMoreElements()) {
  375. InetAddress addr = bindings.nextElement();
  376. String networkInterfaceIpAddress = addr.getHostAddress();
  377. // we cache the look up to speed up the next time
  378. cachedAnyLocalAddresses.add(networkInterfaceIpAddress);
  379. }
  380. }
  381. } catch (SocketException e) {
  382. logger.logWarning("Unable to enumerate network interfaces. Binding to 0.0.0.0 may not work.");
  383. }
  384. } else {
  385. ipAddresses.addAll(cachedAnyLocalAddresses);
  386. }
  387. } else {
  388. ipAddresses.add(address);
  389. }
  390. String httpPortString = System.getProperty("org.mobicents.properties.httpPort");
  391. String sslPortString = System.getProperty("org.mobicents.properties.sslPort");
  392. for (String ipAddress : ipAddresses) {
  393. SIPNode node = new SIPNode(hostName, ipAddress);
  394. int httpPort = 0;
  395. int sslPort = 0;
  396. if(httpPortString != null) {
  397. httpPort = Integer.parseInt(httpPortString);
  398. node.getProperties().put("httpPort", httpPort);
  399. }
  400. if(sslPortString != null) {
  401. sslPort = Integer.parseInt(sslPortString);
  402. node.getProperties().put("sslPort", sslPort);
  403. }
  404. if(sipTcpPort != null) node.getProperties().put("tcpPort", sipTcpPort);
  405. if(sipUdpPort != null) node.getProperties().put("udpPort", sipUdpPort);
  406. if(jvmRoute != null) node.getProperties().put("jvmRoute", jvmRoute);
  407. //, port,
  408. // transports, jvmRoute, httpPort, sslPort, null);
  409. info.add(node);
  410. }
  411. return info;
  412. }
  413. /**
  414. * @param info
  415. */
  416. protected void sendKeepAliveToBalancers(ArrayList<SIPNode> info) {
  417. Thread.currentThread().setContextClassLoader(NodeRegisterRMIStub.class.getClassLoader());
  418. for(SipLoadBalancer balancerDescription:new HashSet<SipLoadBalancer>(register.values())) {
  419. try {
  420. Registry registry = LocateRegistry.getRegistry(balancerDescription.getAddress().getHostAddress(), balancerDescription.getRmiPort());
  421. NodeRegisterRMIStub reg=(NodeRegisterRMIStub) registry.lookup("SIPBalancer");
  422. ArrayList<SIPNode> reachableInfo = getReachableSIPNodeInfo(balancerDescription.getAddress(), info);
  423. if(reachableInfo.isEmpty()) {
  424. logger.logWarning("All connectors are unreachable from the balancer");
  425. }
  426. reg.handlePing(reachableInfo);
  427. balancerDescription.setDisplayWarning(true);
  428. if(!balancerDescription.isAvailable()) {
  429. logger.logInfo("Keepalive: SIP Load Balancer Found! " + balancerDescription);
  430. }
  431. balancerDescription.setAvailable(true);
  432. } catch (Exception e) {
  433. balancerDescription.setAvailable(false);
  434. if(balancerDescription.isDisplayWarning()) {
  435. logger.logWarning("Cannot access the SIP load balancer RMI registry: " + e.getMessage() +
  436. "\nIf you need a cluster configuration make sure the SIP load balancer is running. Host " + balancerDescription.toString());
  437. }
  438. balancerDescription.setDisplayWarning(false);
  439. }
  440. }
  441. if(logger.isLoggingEnabled(StackLogger.TRACE_TRACE)) {
  442. logger.logTrace("Finished gathering, Gathered info[" + info + "]");
  443. }
  444. }
  445. /**
  446. * Contribution from Naoki Nishihara from OKI for Issue 1806 (SIP LB can not forward when node is listening on 0.0.0.0)
  447. * Useful for a multi homed address, tries to reach a given load balancer from the list of ip addresses given in param
  448. * @param balancerAddr the load balancer to try to reach
  449. * @param info the list of node info from which we try to access the load balancer
  450. * @return the list stripped from the nodes not able to reach the load balancer
  451. */
  452. protected ArrayList<SIPNode> getReachableSIPNodeInfo(InetAddress balancerAddr, ArrayList<SIPNode> info) {
  453. if (balancerAddr.isLoopbackAddress()) {
  454. return info;
  455. }
  456. ArrayList<SIPNode> rv = new ArrayList<SIPNode>();
  457. for(SIPNode node: info) {
  458. try {
  459. NetworkInterface ni = NetworkInterface.getByInetAddress(InetAddress.getByName(node.getIp()));
  460. // FIXME How can I determine the ttl?
  461. boolean b = balancerAddr.isReachable(ni, 5, 900);
  462. if(b) {
  463. rv.add(node);
  464. }
  465. } catch (IOException e) {
  466. logger.logError("IOException", e);
  467. }
  468. }
  469. if(logger.isLoggingEnabled(StackLogger.TRACE_TRACE)) {
  470. logger.logTrace("Reachable SIP Node:[balancer=" + balancerAddr + "],[node info=" + rv + "]");
  471. }
  472. return rv;
  473. }
  474. /**
  475. * @param info
  476. */
  477. protected void removeNodesFromBalancers(ArrayList<SIPNode> info) {
  478. Thread.currentThread().setContextClassLoader(NodeRegisterRMIStub.class.getClassLoader());
  479. for(SipLoadBalancer balancerDescription:new HashSet<SipLoadBalancer>(register.values())) {
  480. try {
  481. Registry registry = LocateRegistry.getRegistry(balancerDescription.getAddress().getHostAddress(),balancerDescription.getRmiPort());
  482. NodeRegisterRMIStub reg=(NodeRegisterRMIStub) registry.lookup("SIPBalancer");
  483. reg.forceRemoval(info);
  484. if(!balancerDescription.isAvailable()) {
  485. logger.logInfo("Remove: SIP Load Balancer Found! " + balancerDescription);
  486. balancerDescription.setDisplayWarning(true);
  487. }
  488. balancerDescription.setAvailable(true);
  489. } catch (Exception e) {
  490. if(balancerDescription.isDisplayWarning()) {
  491. logger.logWarning("Cannot access the SIP load balancer RMI registry: " + e.getMessage() +
  492. "\nIf you need a cluster configuration make sure the SIP load balancer is running.");
  493. // logger.error("Cannot access the SIP load balancer RMI registry: " , e);
  494. balancerDescription.setDisplayWarning(false);
  495. }
  496. balancerDescription.setAvailable(true);
  497. }
  498. }
  499. if(logger.isLoggingEnabled(StackLogger.TRACE_TRACE)) {
  500. logger.logTrace("Finished gathering, Gathered info[" + info + "]");
  501. }
  502. }
  503. /**
  504. *
  505. * @author <A HREF="mailto:jean.deruelle@gmail.com">Jean Deruelle</A>
  506. *
  507. */
  508. protected class BalancerPingTimerTask extends TimerTask {
  509. @SuppressWarnings("unchecked")
  510. @Override
  511. public void run() {
  512. ArrayList<SIPNode> info = getConnectorsAsSIPNode();
  513. sendKeepAliveToBalancers(info);
  514. }
  515. }
  516. /**
  517. * @param balancers the balancers to set
  518. */
  519. public void setBalancers(String balancers) {
  520. this.balancers = balancers;
  521. }
  522. /**
  523. * @return the jvmRoute
  524. */
  525. public String getJvmRoute() {
  526. return jvmRoute;
  527. }
  528. /**
  529. * @param jvmRoute the jvmRoute to set
  530. */
  531. public void setJvmRoute(String jvmRoute) {
  532. this.jvmRoute = jvmRoute;
  533. }
  534. public void addLoadBalancerHeartBeatingListener(
  535. LoadBalancerHeartBeatingListener loadBalancerHeartBeatingListener) {
  536. loadBalancerHeartBeatingListeners.add(loadBalancerHeartBeatingListener);
  537. }
  538. public void removeLoadBalancerHeartBeatingListener(
  539. LoadBalancerHeartBeatingListener loadBalancerHeartBeatingListener) {
  540. loadBalancerHeartBeatingListeners.remove(loadBalancerHeartBeatingListener);
  541. }
  542. /**
  543. * @param info
  544. */
  545. public void sendSwitchoverInstruction(SipLoadBalancer sipLoadBalancer, String fromJvmRoute, String toJvmRoute) {
  546. logger.logInfo("switching over from " + fromJvmRoute + " to " + toJvmRoute);
  547. if(fromJvmRoute == null || toJvmRoute == null) {
  548. return;
  549. }
  550. ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
  551. try {
  552. Thread.currentThread().setContextClassLoader(NodeRegisterRMIStub.class.getClassLoader());
  553. Registry registry = LocateRegistry.getRegistry(sipLoadBalancer.getAddress().getHostAddress(),sipLoadBalancer.getRmiPort());
  554. NodeRegisterRMIStub reg=(NodeRegisterRMIStub) registry.lookup("SIPBalancer");
  555. reg.switchover(fromJvmRoute, toJvmRoute);
  556. sipLoadBalancer.setDisplayWarning(true);
  557. if(!sipLoadBalancer.isAvailable()) {
  558. logger.logInfo("Switchover: SIP Load Balancer Found! " + sipLoadBalancer);
  559. }
  560. } catch (Exception e) {
  561. sipLoadBalancer.setAvailable(false);
  562. if(sipLoadBalancer.isDisplayWarning()) {
  563. logger.logWarning("Cannot access the SIP load balancer RMI registry: " + e.getMessage() +
  564. "\nIf you need a cluster configuration make sure the SIP load balancer is running.");
  565. // logger.error("Cannot access the SIP load balancer RMI registry: " , e);
  566. sipLoadBalancer.setDisplayWarning(false);
  567. }
  568. } finally {
  569. Thread.currentThread().setContextClassLoader(oldClassLoader);
  570. }
  571. }
  572. public SipLoadBalancer[] getLoadBalancers() {
  573. // This is slow, but it is called rarely, so no prob
  574. return register.values().toArray(new SipLoadBalancer[] {});
  575. }
  576. }