package com.sequenceiq.periscope.service.registry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.xbill.DNS.Lookup; import org.xbill.DNS.Record; import org.xbill.DNS.SRVRecord; import org.xbill.DNS.TextParseException; import org.xbill.DNS.Type; @Component public class DNSServiceAddressResolver implements ServiceAddressResolver { private static final Logger LOGGER = LoggerFactory.getLogger(DNSServiceAddressResolver.class); public String resolveUrl(String serviceUrl, String protocol, String serviceId) throws ServiceAddressResolvingException { String resolvedAddress; if (!StringUtils.isEmpty(serviceUrl)) { resolvedAddress = serviceUrl; } else if (!StringUtils.isEmpty(protocol) && !StringUtils.isEmpty(serviceId)) { resolvedAddress = protocol + "://" + dnsSrvLookup(serviceId); } else { throw new IllegalArgumentException("serviceUrl or (protocol, serviceId) must be given!"); } return resolvedAddress; } public String resolveHostPort(String serviceHost, String servicePort, String serviceId) throws ServiceAddressResolvingException { String resolvedAddress; if (!StringUtils.isEmpty(serviceHost) && !StringUtils.isEmpty(servicePort)) { resolvedAddress = serviceHost + ":" + servicePort; } else if (!StringUtils.isEmpty(serviceId)) { resolvedAddress = dnsSrvLookup(serviceId); } else { throw new IllegalArgumentException("(serviceHost, servicePort) or serviceId must be given!"); } return resolvedAddress; } private String dnsSrvLookup(String query) throws ServiceAddressResolvingException { String result; try { Record[] records = new Lookup(query, Type.SRV).run(); if (records != null && records.length > 0) { SRVRecord srv = (SRVRecord) records[0]; result = srv.getTarget().toString().replaceFirst("\\.$", "") + ":" + srv.getPort(); } else { throw new ServiceAddressResolvingException("The Service " + query + " cannot be resolved"); } } catch (TextParseException e) { throw new ServiceAddressResolvingException("The Service " + query + " cannot be resolved", e); } return result; } }