PageRenderTime 148ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/MDCDiscovery/src/main/java/org/smpte/_2071/_2012/mdcd/net/NetworkTopologyDiscoveryServiceImpl.java

https://bitbucket.org/psymes/34cs-st2071
Java | 432 lines | 354 code | 78 blank | 0 comment | 60 complexity | 79769d4ce6ed42a042baadb63efdf95d MD5 | raw file
  1. package org.smpte._2071._2012.mdcd.net;
  2. import java.net.InetAddress;
  3. import java.net.InterfaceAddress;
  4. import java.net.NetworkInterface;
  5. import java.net.SocketException;
  6. import java.util.ArrayList;
  7. import java.util.Arrays;
  8. import java.util.Collections;
  9. import java.util.Enumeration;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import java.util.Timer;
  14. import java.util.TimerTask;
  15. import java.util.concurrent.ConcurrentHashMap;
  16. import java.util.concurrent.CopyOnWriteArraySet;
  17. import java.util.logging.Level;
  18. import java.util.logging.Logger;
  19. import org.smpte._2071._2012.mdcd.impl.Utils;
  20. public class NetworkTopologyDiscoveryServiceImpl implements NetworkTopologyDiscoveryService
  21. {
  22. static class TopologyPoller extends TimerTask
  23. {
  24. private final Logger log = Logger.getLogger(getClass().getName());
  25. private Timer timer = new Timer();
  26. private transient boolean started = false;
  27. private NetworkTopologyDiscoveryService topologyDiscovery;
  28. private Map<NetworkInterface, List<InetAddress>> knownInterfaces = new ConcurrentHashMap<NetworkInterface, List<InetAddress>>();
  29. TopologyPoller(NetworkTopologyDiscoveryService topologyDiscovery)
  30. {
  31. this.topologyDiscovery = topologyDiscovery;
  32. }
  33. public synchronized boolean isStarted()
  34. {
  35. return started;
  36. }
  37. public synchronized void start()
  38. {
  39. log.fine("Network Topology Poller Starting");
  40. started = true;
  41. timer.schedule(this, 0, 60000);
  42. log.info("Network Topology Poller Started");
  43. }
  44. public synchronized void stop()
  45. {
  46. log.fine("Network Topology Poller Stopping");
  47. started = false;
  48. timer.cancel();
  49. log.info("Network Topology Poller Stopped");
  50. }
  51. @Override
  52. public void run()
  53. {
  54. try
  55. {
  56. log.fine("Polling Network Topology");
  57. Map<NetworkInterface, List<InetAddress>> newInterfaces = topologyDiscovery.listAddresses();
  58. for (Map.Entry<NetworkInterface, List<InetAddress>> entry : newInterfaces.entrySet())
  59. {
  60. if (!knownInterfaces.containsKey(entry.getKey()))
  61. {
  62. knownInterfaces.put(entry.getKey(), entry.getValue());
  63. topologyDiscovery.interfaceAdded(entry.getKey(), entry.getValue());
  64. } else
  65. {
  66. List<InetAddress> knownAddresses = knownInterfaces.get(entry.getKey());
  67. if (knownAddresses != null && !knownAddresses.isEmpty() && entry.getValue() != null && !entry.getValue().isEmpty())
  68. {
  69. List<InetAddress> newAddresses = new ArrayList<InetAddress>();
  70. for (InetAddress newAddress : entry.getValue())
  71. {
  72. if (!knownAddresses.contains(newAddress))
  73. {
  74. newAddresses.add(newAddress);
  75. topologyDiscovery.addressAdded(entry.getKey(), newAddress);
  76. }
  77. }
  78. knownAddresses.addAll(newAddresses);
  79. }
  80. }
  81. }
  82. for (Map.Entry<NetworkInterface, List<InetAddress>> entry : knownInterfaces.entrySet())
  83. {
  84. if (!newInterfaces.containsKey(entry.getKey()))
  85. {
  86. knownInterfaces.remove(entry.getKey());
  87. topologyDiscovery.interfaceRemoved(entry.getKey(), entry.getValue());
  88. } else
  89. {
  90. List<InetAddress> knownAddresses = entry.getValue();
  91. List<InetAddress> newAddresses = newInterfaces.get(entry.getKey());
  92. if (newAddresses != null && !newAddresses.isEmpty() && entry.getValue() != null && !entry.getValue().isEmpty())
  93. {
  94. List<InetAddress> removedAddresses = new ArrayList<InetAddress>();
  95. for (InetAddress knownAddress : entry.getValue())
  96. {
  97. if (!newAddresses.contains(knownAddress))
  98. {
  99. removedAddresses.add(knownAddress);
  100. topologyDiscovery.addressRemoved(entry.getKey(), knownAddress);
  101. }
  102. }
  103. knownAddresses.removeAll(removedAddresses);
  104. }
  105. }
  106. }
  107. } catch (Throwable t)
  108. {
  109. Utils.log(log, Level.WARNING, t.getMessage(), Level.FINE, t);
  110. }
  111. }
  112. @Override
  113. protected void finalize()
  114. {
  115. stop();
  116. }
  117. }
  118. private final Logger log = Logger.getLogger(getClass().getName());
  119. private CopyOnWriteArraySet<NetworkTopologyListener> listeners = new CopyOnWriteArraySet<NetworkTopologyListener>();
  120. private boolean useIPv6;
  121. private boolean useSiteLocal;
  122. private boolean useVirtual;
  123. private boolean useLoopback;
  124. private TopologyPoller topologyPoller = new TopologyPoller(this);
  125. public NetworkTopologyDiscoveryServiceImpl(boolean useIPv6, boolean useSiteLocal, boolean useVirtual, boolean useLoopback)
  126. {
  127. this.useIPv6 = useIPv6;
  128. this.useSiteLocal = useSiteLocal;
  129. this.useVirtual = useVirtual;
  130. this.useLoopback = useLoopback;
  131. }
  132. public void start()
  133. {
  134. log.fine("Network Topology Monitor Starting");
  135. log.info("Network Topology Monitor Started");
  136. }
  137. public void stop()
  138. {
  139. log.fine("Network Topology Monitor Stopping");
  140. topologyPoller.stop();
  141. log.info("Network Topology Monitor Stopped");
  142. }
  143. public Map<NetworkInterface, List<InetAddress>> listAddresses()
  144. throws SocketException
  145. {
  146. Map<NetworkInterface, List<InetAddress>> interfaces = new HashMap<NetworkInterface, List<InetAddress>>();
  147. Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
  148. while (ifaces.hasMoreElements())
  149. {
  150. NetworkInterface networkInterface = ifaces.nextElement();
  151. if (useNetworkInterface(networkInterface))
  152. {
  153. Enumeration<InetAddress> addrs = networkInterface.getInetAddresses();
  154. while (addrs.hasMoreElements())
  155. {
  156. InetAddress inetAddress = addrs.nextElement();
  157. if (useInetAddress(inetAddress))
  158. {
  159. List<InetAddress> addresses = interfaces.get(networkInterface);
  160. if (addresses == null)
  161. {
  162. addresses = new ArrayList<InetAddress>();
  163. interfaces.put(networkInterface, addresses);
  164. }
  165. addresses.add(inetAddress);
  166. }
  167. }
  168. }
  169. if (useVirtual)
  170. {
  171. Enumeration<NetworkInterface> virtualIfaces = networkInterface.getSubInterfaces();
  172. while (virtualIfaces.hasMoreElements())
  173. {
  174. NetworkInterface subNetworkInterface = virtualIfaces.nextElement();
  175. if (useNetworkInterface(networkInterface))
  176. {
  177. Enumeration<InetAddress> addrs = subNetworkInterface.getInetAddresses();
  178. while (addrs.hasMoreElements())
  179. {
  180. InetAddress inetAddress = addrs.nextElement();
  181. if (useInetAddress(inetAddress))
  182. {
  183. List<InetAddress> addresses = interfaces.get(networkInterface);
  184. if (addresses == null)
  185. {
  186. addresses = new ArrayList<InetAddress>();
  187. interfaces.put(networkInterface, addresses);
  188. }
  189. addresses.add(inetAddress);
  190. }
  191. }
  192. }
  193. }
  194. }
  195. }
  196. return Collections.unmodifiableMap(interfaces);
  197. }
  198. public boolean isMonitoringIPv6()
  199. {
  200. return useIPv6;
  201. }
  202. public boolean isMonitoringSiteLocal()
  203. {
  204. return useSiteLocal;
  205. }
  206. public boolean isMonitoringVirtual()
  207. {
  208. return useVirtual;
  209. }
  210. public boolean isMonitoringLoopback()
  211. {
  212. return useLoopback;
  213. }
  214. protected boolean useNetworkInterface(NetworkInterface networkInterface)
  215. {
  216. if (useVirtual && networkInterface.isVirtual())
  217. {
  218. return true;
  219. }
  220. try
  221. {
  222. if (useLoopback && networkInterface.isLoopback())
  223. {
  224. return true;
  225. }
  226. return networkInterface.isUp();
  227. } catch (SocketException e)
  228. {
  229. return false;
  230. }
  231. }
  232. protected boolean useInetAddress(InetAddress inetAddress)
  233. {
  234. if ((useSiteLocal && (inetAddress.isSiteLocalAddress() || inetAddress.isLinkLocalAddress() || inetAddress.isAnyLocalAddress())) ||
  235. (useLoopback && inetAddress.isLoopbackAddress()))
  236. {
  237. if (useIPv6)
  238. {
  239. return true;
  240. } else
  241. {
  242. return inetAddress.getAddress().length == 4;
  243. }
  244. }
  245. return false;
  246. }
  247. public void addNetworkTopologyListener(NetworkTopologyListener listener)
  248. {
  249. listeners.add(listener);
  250. if (listeners.size() > 0 && !topologyPoller.isStarted())
  251. {
  252. topologyPoller.start();
  253. }
  254. }
  255. public void removeNetworkTopologyListener(NetworkTopologyListener listener)
  256. {
  257. listeners.remove(listener);
  258. if (listeners.size() <= 0 && topologyPoller.isStarted())
  259. {
  260. topologyPoller.stop();
  261. }
  262. }
  263. public void interfaceAdded(NetworkInterface networkInterface, List<InetAddress> addresses)
  264. {
  265. log.fine("Network Interface \"" + networkInterface + "\" for Addresses " + addresses + " Added.");
  266. for (NetworkTopologyListener listener : listeners)
  267. {
  268. try
  269. {
  270. listener.interfaceAdded(networkInterface, addresses);
  271. } catch (Throwable t)
  272. {
  273. log.log(Level.WARNING, "Error senting event to listener [" + listener + "]", t);
  274. }
  275. }
  276. }
  277. @Override
  278. public void interfaceRemoved(NetworkInterface networkInterface, List<InetAddress> addresses)
  279. {
  280. log.fine("Network Interface \"" + networkInterface + "\" for Addresses " + addresses + " Removed.");
  281. for (NetworkTopologyListener listener : listeners)
  282. {
  283. try
  284. {
  285. listener.interfaceRemoved(networkInterface, addresses);
  286. } catch (Throwable t)
  287. {
  288. log.log(Level.WARNING, "Error senting event to listener [" + listener + "]", t);
  289. }
  290. }
  291. }
  292. @Override
  293. public void addressAdded(NetworkInterface networkInterface, InetAddress address)
  294. {
  295. log.fine("Address \"" + address + "\" for Network Interface \"" + networkInterface + "\" Added.");
  296. for (NetworkTopologyListener listener : listeners)
  297. {
  298. try
  299. {
  300. listener.addressAdded(networkInterface, address);
  301. } catch (Throwable t)
  302. {
  303. log.log(Level.WARNING, "Error senting event to listener [" + listener + "]", t);
  304. }
  305. }
  306. }
  307. @Override
  308. public void addressRemoved(NetworkInterface networkInterface, InetAddress address)
  309. {
  310. log.fine("Address \"" + address + "\" for Network Interface \"" + networkInterface + "\" Removed.");
  311. for (NetworkTopologyListener listener : listeners)
  312. {
  313. try
  314. {
  315. listener.addressRemoved(networkInterface, address);
  316. } catch (Throwable t)
  317. {
  318. log.log(Level.WARNING, "Error senting event to listener [" + listener + "]", t);
  319. }
  320. }
  321. }
  322. @Override
  323. public int getNetworkPrefixLength(InetAddress address)
  324. {
  325. try
  326. {
  327. NetworkInterface iface = NetworkInterface.getByInetAddress(address);
  328. if (useNetworkInterface(iface))
  329. {
  330. List<InterfaceAddress> ifaceAddresses = iface.getInterfaceAddresses();
  331. if (ifaceAddresses != null)
  332. {
  333. for (InterfaceAddress ifaceAddress : ifaceAddresses)
  334. {
  335. try
  336. {
  337. if (useInetAddress(ifaceAddress.getAddress()) && ifaceAddress.getAddress().equals(address))
  338. {
  339. return ifaceAddress.getNetworkPrefixLength();
  340. }
  341. } catch (Exception e)
  342. {
  343. Utils.log(log, Level.WARNING, "Could not determine ARPA domain for address \"" + ifaceAddress + "\" on Network Interface \"" + iface + "\"" + (e.getMessage() != null ? " - " + e.getMessage() : "."), Level.FINE, e);
  344. }
  345. }
  346. }
  347. }
  348. } catch (Exception e)
  349. {
  350. Utils.log(log, Level.WARNING, "Error Adding Subnet ARPA domain" + (e.getMessage() != null ? " - " + e.getMessage() : "."), Level.FINE, e);
  351. }
  352. return -1;
  353. }
  354. }