001    /*
002     * The MIT License
003     * Copyright (c) 2012 Microsoft Corporation
004     *
005     * Permission is hereby granted, free of charge, to any person obtaining a copy
006     * of this software and associated documentation files (the "Software"), to deal
007     * in the Software without restriction, including without limitation the rights
008     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
009     * copies of the Software, and to permit persons to whom the Software is
010     * furnished to do so, subject to the following conditions:
011     *
012     * The above copyright notice and this permission notice shall be included in
013     * all copies or substantial portions of the Software.
014     *
015     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
016     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
017     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
018     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
019     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
020     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
021     * THE SOFTWARE.
022     */
023    
024    package microsoft.exchange.webservices.data.dns;
025    
026    import microsoft.exchange.webservices.data.EWSConstants;
027    import microsoft.exchange.webservices.data.core.exception.dns.DnsException;
028    
029    import javax.naming.NamingEnumeration;
030    import javax.naming.NamingException;
031    import javax.naming.directory.Attribute;
032    import javax.naming.directory.Attributes;
033    import javax.naming.directory.DirContext;
034    import javax.naming.directory.InitialDirContext;
035    
036    import java.util.ArrayList;
037    import java.util.Hashtable;
038    import java.util.List;
039    
040    /**
041     * Class that represents DNS Query client.
042     */
043    public class DnsClient {
044    
045      /**
046       * Set up the environment used to construct the DirContext.
047       *
048       * @param dnsServerAddress
049       * @return
050       */
051      static Hashtable<String, String> getEnv(String dnsServerAddress) {
052        // Set up environment for creating initial context
053        Hashtable<String, String> env = new Hashtable<String, String>();
054        env.put("java.naming.factory.initial",
055                "com.sun.jndi.dns.DnsContextFactory");
056        if(dnsServerAddress != null && !dnsServerAddress.isEmpty()) {
057          env.put("java.naming.provider.url", "dns://" + dnsServerAddress);
058        }
059        return env;
060      }
061    
062      /**
063       * Performs Dns query.
064       *
065       * @param <T>              the generic type
066       * @param cls              DnsRecord Type
067       * @param domain           the domain
068       * @param dnsServerAddress IPAddress of DNS server to use (may be null)
069       * @return DnsRecord The DNS record list (never null but may be empty)
070       * @throws DnsException the dns exception
071       */
072    
073      public static <T extends DnsRecord> List<T> dnsQuery(Class<T> cls, String domain, String dnsServerAddress) throws
074                                                                                                                 DnsException {
075    
076        List<T> dnsRecordList = new ArrayList<T>();
077        try {
078          // Create initial context
079          DirContext ictx = new InitialDirContext(getEnv(dnsServerAddress));
080    
081          // Retrieve SRV record context attribute for the specified domain
082          Attributes contextAttributes = ictx.getAttributes(domain,
083              new String[] {EWSConstants.SRVRECORD});
084          if (contextAttributes != null) {
085            NamingEnumeration<?> attributes = contextAttributes.getAll();
086            if (attributes != null) {
087              while (attributes.hasMore()) {
088                Attribute attr = (Attribute) attributes.next();
089                NamingEnumeration<?> srvValues = attr.getAll();
090                if (srvValues != null) {
091                  while (srvValues.hasMore()) {
092                    T dnsRecord = cls.newInstance();
093    
094                    // Loads the DNS SRV record
095                    dnsRecord.load((String) srvValues.next());
096                    dnsRecordList.add(dnsRecord);
097                  }
098                }
099              }
100            }
101          }
102        } catch (NamingException ne) {
103          throw new DnsException(ne.getMessage());
104        } catch (Exception e) {
105          throw new DnsException(e.getMessage());
106        }
107        return dnsRecordList;
108      }
109    }