PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/MDCDiscovery/src/main/java/org/smpte/_2071/_2012/mdcd/naming/jndi/NamingServiceImpl.java

https://bitbucket.org/psymes/34cs-st2071
Java | 394 lines | 346 code | 46 blank | 2 comment | 53 complexity | 0f944d8eeb82c115c3848e9f536837e3 MD5 | raw file
  1. package org.smpte._2071._2012.mdcd.naming.jndi;
  2. import java.io.IOException;
  3. import java.net.InetAddress;
  4. import java.net.UnknownHostException;
  5. import java.util.ArrayList;
  6. import java.util.Arrays;
  7. import java.util.Hashtable;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.util.logging.Level;
  11. import javax.naming.Context;
  12. import javax.naming.NamingEnumeration;
  13. import javax.naming.NamingException;
  14. import javax.naming.directory.Attribute;
  15. import javax.naming.directory.Attributes;
  16. import javax.naming.directory.DirContext;
  17. import javax.naming.directory.InitialDirContext;
  18. import org.smpte._2071._2012.mdcd.ServiceInstance;
  19. import org.smpte._2071._2012.mdcd.ServiceName;
  20. import org.smpte._2071._2012.mdcd.impl.Utils;
  21. import org.smpte._2071._2012.mdcd.naming.AbstractNamingServiceImpl;
  22. import org.smpte._2071._2012.mdcd.naming.NameRecord;
  23. import org.smpte._2071._2012.mdcd.net.InetAddressUtils;
  24. public class NamingServiceImpl extends AbstractNamingServiceImpl
  25. {
  26. private static final String[] QUERY_TYPES = new String[] {"A", "PTR", "SRV"};
  27. private static final String[] PTR_TYPES = new String[] {"PTR"};
  28. private static final String[] SRV_TYPES = new String[] {"PTR", "SRV"};
  29. private static final String[] TXT_TYPES = new String[] {"TXT"};
  30. private static final String[] ADDRESS_TYPES = new String[] {"A", "AAAA"};
  31. private Hashtable<String, String> env = new Hashtable<String, String>();
  32. private DirContext context;
  33. public NamingServiceImpl()
  34. throws NamingException
  35. {
  36. env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
  37. context = new InitialDirContext(env);
  38. }
  39. @Override
  40. public List<NameRecord> reverseQuery(InetAddress address)
  41. throws NamingException
  42. {
  43. ArrayList<NameRecord> list = new ArrayList<NameRecord>();
  44. Attributes attrs = context.getAttributes(InetAddressUtils.reverseMapAddress(address), PTR_TYPES);
  45. NamingEnumeration<? extends Attribute> enumerator = attrs.getAll();
  46. while (enumerator.hasMore())
  47. {
  48. Attribute attr = enumerator.next();
  49. String type = attr.getID();
  50. if ("PTR".equals(type))
  51. {
  52. NamingEnumeration<?> values = attr.getAll();
  53. while (values.hasMore())
  54. {
  55. Object value = values.next();
  56. if (value != null)
  57. {
  58. list.add(new NameRecord(value.toString(), address));
  59. }
  60. }
  61. }
  62. }
  63. return list;
  64. }
  65. @Override
  66. public List<NameRecord> query(ServiceName serviceName)
  67. throws NamingException
  68. {
  69. ArrayList<NameRecord> list = new ArrayList<NameRecord>();
  70. try
  71. {
  72. Attributes attrs = context.getAttributes(serviceName.toString(), QUERY_TYPES);
  73. NamingEnumeration<? extends Attribute> enumerator = attrs.getAll();
  74. while (enumerator.hasMore())
  75. {
  76. Attribute attr = enumerator.next();
  77. String type = attr.getID();
  78. if ("PTR".equals(type))
  79. {
  80. NamingEnumeration<?> values = attr.getAll();
  81. while (values.hasMore())
  82. {
  83. Object value = values.next();
  84. if (value != null)
  85. {
  86. list.add(new NameRecord(value.toString(), (InetAddress) null));
  87. }
  88. }
  89. } else if ("SRV".equals(type))
  90. {
  91. NamingEnumeration<?> values = attr.getAll();
  92. while (values.hasMore())
  93. {
  94. Object value = values.next();
  95. if (value != null)
  96. {
  97. list.add(new NameRecord(parseHostFromSRV(value.toString()), (InetAddress) null));
  98. }
  99. }
  100. } else if ("A".equals(type))
  101. {
  102. NamingEnumeration<?> values = attr.getAll();
  103. while (values.hasMore())
  104. {
  105. Object value = values.next();
  106. if (value != null)
  107. {
  108. try
  109. {
  110. list.add(new NameRecord(serviceName.toString(), InetAddress.getByName(value.toString())));
  111. } catch (UnknownHostException e)
  112. {
  113. Utils.log(log, Level.WARNING, e.getMessage(), Level.FINE, e);
  114. }
  115. }
  116. }
  117. }
  118. }
  119. } catch (NamingException e)
  120. {
  121. Utils.log(log, Level.WARNING, "Issue querying " + Arrays.toString(QUERY_TYPES) + " for \"" + serviceName + "\" " + e.getMessage() + " - " + e.getExplanation(), Level.FINE, e);
  122. }
  123. return list;
  124. }
  125. private String parseHostFromSRV(String srv)
  126. {
  127. if (srv != null)
  128. {
  129. String string = srv.trim();
  130. int pos = 0;
  131. for (int index = 0; index < 3 && pos != -1; index++)
  132. {
  133. pos = string.indexOf(' ', pos + 1);
  134. }
  135. if (pos > 0)
  136. {
  137. pos++;
  138. if (pos < string.length())
  139. {
  140. return string.substring(pos);
  141. } else
  142. {
  143. return "";
  144. }
  145. } else
  146. {
  147. return null;
  148. }
  149. } else
  150. {
  151. return null;
  152. }
  153. }
  154. @Override
  155. public List<ServiceInstance> serviceDiscovery(ServiceName serviceName)
  156. throws NamingException
  157. {
  158. ArrayList<ServiceInstance> services = new ArrayList<ServiceInstance>();
  159. Attributes attrs = null;
  160. try
  161. {
  162. attrs = context.getAttributes(serviceName.toString(), SRV_TYPES);
  163. } catch (NamingException e)
  164. {
  165. Utils.log(log, Level.WARNING, "Issue querying " + Arrays.toString(SRV_TYPES) + " \"" + serviceName + "\"" + e.getMessage() + " - " + e.getExplanation(), Level.FINE, e);
  166. }
  167. if (attrs == null)
  168. {
  169. return services;
  170. }
  171. NamingEnumeration<? extends Attribute> enumerator = attrs.getAll();
  172. while (enumerator.hasMore())
  173. {
  174. Attribute attr = enumerator.next();
  175. String type = attr.getID();
  176. if ("PTR".equals(type))
  177. {
  178. NamingEnumeration<?> values = attr.getAll();
  179. while (values.hasMore())
  180. {
  181. Object value = values.next();
  182. if (value != null)
  183. {
  184. try
  185. {
  186. services.addAll(serviceDiscovery(new ServiceName(value.toString())));
  187. } catch (NamingException e)
  188. {
  189. // Already Logged
  190. }
  191. }
  192. }
  193. } else if ("SRV".equals(type))
  194. {
  195. NamingEnumeration<?> values = attr.getAll();
  196. while (values.hasMore())
  197. {
  198. Object value = values.next();
  199. if (value != null)
  200. {
  201. ServiceInstance service = parseSRVRecord(serviceName, value.toString());
  202. services.add(service);
  203. try
  204. {
  205. ArrayList<String> textRecords = new ArrayList<String>();
  206. Attributes txtAttrs = context.getAttributes(serviceName.toString(), TXT_TYPES);
  207. NamingEnumeration<? extends Attribute> txtEnumerator = txtAttrs.getAll();
  208. while (txtEnumerator.hasMore())
  209. {
  210. Attribute txtAttr = txtEnumerator.next();
  211. NamingEnumeration<?> txtValues = txtAttr.getAll();
  212. while (txtValues.hasMore())
  213. {
  214. Object txtValue = txtValues.next();
  215. if (txtValue != null)
  216. {
  217. textRecords.add(txtValue.toString());
  218. }
  219. }
  220. }
  221. service.addTextRecords(textRecords);
  222. } catch (NamingException e)
  223. {
  224. Utils.log(log, Level.WARNING, "Issue querying " + TXT_TYPES + " Record for \"" + serviceName + "\" " + e.getMessage() + " - " + e.getExplanation(), Level.FINE, e);
  225. throw new NamingException("DNS-SD Error: Could not find " + Arrays.toString(TXT_TYPES) + " record for \"" + serviceName + "\" - " + e.getMessage());
  226. }
  227. ArrayList<InetAddress> addresses = new ArrayList<InetAddress>();
  228. try
  229. {
  230. Attributes aAttrs = context.getAttributes(service.getHost(), ADDRESS_TYPES);
  231. NamingEnumeration<? extends Attribute> aEnumerator = aAttrs.getAll();
  232. while (aEnumerator.hasMore())
  233. {
  234. Attribute aAttr = aEnumerator.next();
  235. Object aValue = aAttr.get();
  236. if (aValue != null)
  237. {
  238. try
  239. {
  240. addresses.add(InetAddress.getByName(aValue.toString()));
  241. } catch (Exception e)
  242. {
  243. Utils.log(log, Level.WARNING, e.getMessage(), Level.FINE, e);
  244. }
  245. }
  246. }
  247. service.setAddresses(addresses);
  248. } catch (NamingException e)
  249. {
  250. Utils.log(log, Level.WARNING, "Issue querying " + Arrays.toString(ADDRESS_TYPES) + " \"" + service.getHost() + "\"" + e.getMessage() + " - " + e.getExplanation(), Level.FINE, e);
  251. }
  252. }
  253. }
  254. }
  255. }
  256. return services;
  257. }
  258. private ServiceInstance parseSRVRecord(ServiceName serviceName, String string)
  259. {
  260. if (string == null)
  261. {
  262. return null;
  263. }
  264. int priority = -1;
  265. int weight = -1;
  266. int port = -1;
  267. String host = null;
  268. String target = null;
  269. int column = 0;
  270. int length = string.length();
  271. StringBuilder buffer = new StringBuilder();
  272. for (int index = 0; index <= length; index++)
  273. {
  274. char c;
  275. if (index == length)
  276. {
  277. c = ' ';
  278. } else
  279. {
  280. c = string.charAt(index);
  281. }
  282. if (Character.isWhitespace(c))
  283. {
  284. switch (column++)
  285. {
  286. case 0 :
  287. try
  288. {
  289. priority = Integer.parseInt(buffer.toString());
  290. } catch (Exception e)
  291. {
  292. Utils.log(log, Level.WARNING, e.getMessage(), Level.FINE, e);
  293. }
  294. break;
  295. case 1 :
  296. try
  297. {
  298. weight = Integer.parseInt(buffer.toString());
  299. } catch (Exception e)
  300. {
  301. Utils.log(log, Level.WARNING, e.getMessage(), Level.FINE, e);
  302. }
  303. break;
  304. case 2 :
  305. try
  306. {
  307. port = Integer.parseInt(buffer.toString());
  308. } catch (Exception e)
  309. {
  310. Utils.log(log, Level.WARNING, e.getMessage(), Level.FINE, e);
  311. }
  312. break;
  313. case 3 :
  314. target = host = buffer.toString();
  315. break;
  316. }
  317. buffer.setLength(0);
  318. } else
  319. {
  320. buffer.append(c);
  321. }
  322. }
  323. return new ServiceInstance(serviceName, priority, weight, port, host, (List<InetAddress>) null, target, (Map<String, String>) null);
  324. }
  325. @Override
  326. public void close()
  327. throws IOException
  328. {
  329. try
  330. {
  331. context.close();
  332. } catch (NamingException e)
  333. {
  334. Utils.convertThrowable(IOException.class, "Error closing JNDI Naming Service - " + e.getMessage(), e);
  335. }
  336. }
  337. public static void main(String[] args)
  338. throws Exception
  339. {
  340. // org.smpte._2071._2012.mdcd.naming.dnsjava.NamingServiceImpl namingService = new org.smpte._2071._2012.mdcd.naming.dnsjava.NamingServiceImpl();
  341. NamingServiceImpl namingService = new NamingServiceImpl();
  342. List<ServiceInstance> records = namingService.serviceDiscovery(new ServiceName("_mdc._tcp.mdc.espn.pvt"));
  343. System.out.println(records);
  344. List<NameRecord> names = namingService.query(new ServiceName("Root._device_v1._sub._mdc._tcp.mdc.espn.pvt"));
  345. System.out.println(names);
  346. namingService.close();
  347. }
  348. }