package com.verisign.iot.discovery.domain; import java.util.Objects; import org.xbill.DNS.SRVRecord; /** * Class to capture service related information from DNS i.e. SRV record. This class implements * {@link Comparable} to sort the service instance related information based on priority. * * @see <a href="http://en.wikipedia.org/wiki/SRV_record">SRV Resource Record</a> * @see <a href="http://tools.ietf.org/html/rfc2782">RFC 2782</a> * @author nchigurupati * @version 1.0 * @since Mar 30, 2015 */ public final class ServiceRecord extends DiscoveryRecord { /** * Service host. */ private final String host; /** * Service port. */ private final int port; /** * Service overall priority (i.e. with reference to other instances). */ private final int priority; /** * Service overall weight (i.e. with reference to other instances). */ private final int weight; /** * Static builder. It wraps out a {@link SRVRecord} by extracting relevant data. * * @param srvRecord A {@link SRVRecord} instance to be worked out * @return An instance of <code>ServiceRecord</code> */ public static ServiceRecord build(SRVRecord srvRecord) { return new ServiceRecord(srvRecord.getTarget().toString(), srvRecord.getPort(), srvRecord.getPriority(), srvRecord.getWeight(), srvRecord.getTTL()); } /** * Returns the host * * @return the host */ public String getHost() { return this.host; } /** * Returns the port * * @return the port */ public int getPort() { return this.port; } /** * Returns the priority * * @return the priority */ public int getPriority() { return this.priority; } /** * Returns the weight * * @return the weight */ public int getWeight() { return this.weight; } /** * Returns the ttl * * @return the ttl */ @Override public long getTtl() { return this.ttl; } @Override public int hashCode() { return Objects.hash(this.host, this.port, this.priority, this.weight, this.ttl); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (this.getClass() != obj.getClass()) { return false; } final ServiceRecord that = (ServiceRecord) obj; return compareTo(that) == 0; } @Override public String toString() { return String.format("%d %s:%d", ttl, (host.endsWith(".") ? host.substring(0, host.length() - 1) : host), port); } @Override public int compareTo(DiscoveryRecord other) { if (other instanceof ServiceRecord) { ServiceRecord real = (ServiceRecord) other; if (this.priority < real.priority) { return -1; } else if (this.priority > real.priority) { return 1; } else if (this.weight > real.weight) { return -1; } else if (this.weight < real.weight) { return 1; } else if (!this.host.equals(real.host)) { return this.host.compareTo(real.host); } else if (this.port > real.port) { return 1; } else if (this.port < real.port) { return -1; } } else { return this.compareTo(other); } return 0; } private ServiceRecord(String host, int port, int priority, int weight, long ttl) { super(String.format("%s %d %d %d %d", host, port, priority, weight, ttl), ttl); this.host = host; this.port = port; this.priority = priority; this.weight = weight; } @Override public String getServiceType() { throw new UnsupportedOperationException("Not supported yet."); } @Override public String getServiceZone(String dnsLabel) { throw new UnsupportedOperationException("Not supported yet."); } @Override public String getServiceName(String dnsLabel) { throw new UnsupportedOperationException("Not supported yet."); } @Override public String toDisplay() { return String.format("%d SRV %d %d %s:%d", ttl, priority, weight, (host.endsWith(".") ? host.substring(0, host.length() - 1) : host), port); } }