So, I decided to add a Quartz job that would
1. Query all existing hosts with a valid host name
2. Call a 'dig' on that host
3. Parse an IP address from dig response
So, let's say we have a Host object that looks something like this:
class Host { ... String hostName String ipAddress ... }
Adding a Quartz job is a trivial task that can be easily accomplished using grails Quartz plugin. One advice: use the Quartz plugin instead of manually adding a TimerTask bean using resources.groovy. Apparently, Grails application's most vital aspects, such as autowiring of services and GORM Hibernate session are not available at construction time for beans defined in resources.groovy, because those beans are read before anything in grails-app directory. So, here's how my Quartz job looks in a Grails 1.3.4 application:
import org.codehaus.groovy.grails.commons.ApplicationHolder class IpSynchJob { def hostService def startDelay def timeout public IpSynchJob() { startDelay = 0 timeout = ApplicationHolder.application.config.timer.ipsynch.interval } def execute() { def hosts = Host.createCriteria().list { isNotNull("hostName") } hosts.each { host -> log.info "synching IP for hostname $host.hostName" synchIp(host) } } void synchIp(host) { def dig = digServer(host.hostName) def ipAddress = parseIpFromDigOutput(dig) host.ipAddress = ipAddress host.save() } String parseIpFromDigOutput(digOutput) { // looking for IP address in dig's answer section using positive lookahead def ipInDigPtn = /(ANSWER SECTION\:)(?=\n.*IN\s+A\s+(\d+\.\d+\.\d+\.\d+))/ def ip digOutput.eachMatch(ipInDigPtn) { match -> ip = match[2] } return ip } String digServer(hostName) { Process p = "dig $hostName".execute() int initCapacity = 4096 StringBuffer out = new StringBuffer(initCapacity) p.consumeProcessOutput(out, out) // maxing out wait at 20 seconds p.waitForOrKill(20000) return out.toString() } }