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()
}
}
No comments:
Post a Comment