19 August 2013

Grails - Creating an Auto Dialer - Refactored with Services

After getting some formal Grails training, I decided to refactor this tool I made for our internal provisioning team.

The Original tool was discussed previously here.

Don't Put Too Much Logic in the Controller

I learned that a good MVC practice is to not put too much logic/work in the controller - but to think of controllers as routers.  The body of logic should be pulled out into services.

My previous version of the tool had all the work in the controller.  I had one controller doing this:
  • Parsing a user submitted CSV file
  • Dialing each number in the CSV
  • Emailing the results of each number being active or disconnected, to the requested email
I've changed this, so that the controller just does CSV parsing, and two separate services are handing the phone number dialing and the email sending.

The Refactored Controller

The controller now looks like this:
@Grab('com.xlson.groovycsv:groovycsv:1.0')
import static com.xlson.groovycsv.CsvParser.parseCsv


class CsvImportController {
    def emailService
    def dialerService

    def save() {

  def emailTo = params.emailAdd
  if (emailTo =~ /@myinternaldomain/) {
  def csv = request.getFile('myfile').inputStream.text
  
  def data = parseCsv(csv)

  runAsync{
   for(line in data) {
             def phone = line.Phone
            dialerService.dialNumber(phone)
   
   }
   
            emailService.sendingEmail(emailTo)

   }
  }else{
   render(view:"error") {
     div(id:"error", "E-mail Format Error: E-mail must be from @myinternaldomain.com")
    }
  }
 }
}



The two service calls (dialerService.dialNumber(phone) and emailService.sendingEmail(emailTo), now clean up the controller quite a bit.

Services

There are two new services now:
DialerService and EmailService

The DailerService looks like this:

class DialerService {

    def dialNumber(String phone) {

        println "Trying... $phone"
        def dialNum = "sipcli/sipcli.exe $phone -d [proxy ip goes here] -o 4 -t \"This is a test. this is a test. this is a test. this is a test\"-l 3".execute()
        def outFile = new File("grails-app/test.txt")
        if (dialNum.text =~ /success/){
            outFile << ("PASS on number $phone\r\n")

        } else {
            System.getProperty("line.separator")
            outFile.append("FAIL  on number $phone\r\n")

        }
    }
}

The EmailService looks like this:

class EmailService {

    def sendingEmail(String emailTo) {
        println "Emailing Report To: " + emailTo
        sendMail {
            multipart true
            to "${emailTo}"
            from "brian@someemail.com"
            subject "Provisioning Report"
            body 'Please find the attached Provisioning Report...'
            attachBytes 'grails-app/test.txt','text/csv', new File('grails-app/test.txt').readBytes()
        }
        println "Attempting to delete results file..."
        def delFile = new File("grails-app/test.txt").delete()
    }
}

No comments:

Post a Comment