0

Using grails mail plugin 1.0.7.

https://jira.grails.org/browse/GPMAIL-36 states that it's possible to change plguin configuration since 1.0.1 at runtime. Sadly it does not explains how to achieve it.

I want to be able to change the username at runtime to be able to use different mail accounts.

Thanks.

Rafael
  • 2,521
  • 2
  • 33
  • 59
  • Finally not sure what solution cleaner but, anyway, i must take care about concurrent constraints since the singleton behavior of spring prevents me for doing what im trying to do this way due possible race conditions. If i change the configuration at the sendMail bean (both alternatives do this at the end) any call to sendMail will use that new configuration which is not what i really want but to be able to have control about the configuration for each call. It seems the plugin is not suited for this scenario. – Rafael Dec 30 '14 at 09:30

3 Answers3

2

Based on this code, you should be able to change the configuration at runtime and the mail plugin will automagically re-deploy and update mail sender based on your changes.

Example:

Holders.config.grails.mail.username = 'foo'
Holders.config.grails.mail.password = 'bar'
sendMail {
    to "foo@bar.com"
    from "bar@foo.com"
    subject "Hi"
    body "This is an email"
} 

Update:

It would appear that changing the configuration in this manner does not, in fact, fire the onConfigChange event. Per this, you can fire the event manually. Something like this:

Holders.pluginManager.getGrailsPlugin('mail').notifyOfEvent(GrailsPlugin.EVENT_ON_CONFIG_CHANGE, Holders.config)
rmlan
  • 4,387
  • 2
  • 21
  • 28
  • That's 1.0.8-SNAPSHOT ... i've tested that in 1.0.7 and seems not to work. However i can se the same onConfigChange method so it should. Do you know when the onConfigChange event it's fired or why may this not be working? – Rafael Dec 29 '14 at 17:36
  • The file hasn't changed since 1.0.7: https://github.com/gpc/grails-mail/blob/v1.0.7/MailGrailsPlugin.groovy#L90 – rmlan Dec 29 '14 at 17:47
  • I see but the code you posted is not working ... so it seems the event is not being fired. I am doing this inside a controller's method. – Rafael Dec 29 '14 at 17:51
  • 1
    Hmm, I wonder if this event only fires if `Config.groovy` is changed. Perhaps that is the case. Alternatively, you could fire it yourself. See my updated answer. – rmlan Dec 29 '14 at 18:15
  • Cool ... i'll try that ... so i shall update the properties with Holders.config.grails.mail.username = 'foo' and later manually fire the event Holders.pluginManager.getGrailsPlugin('mail').notifyOfEvent(GrailsPlugin.EVENT_ON_CONFIG_CHANGE, Holders.config) ... right? – Rafael Dec 29 '14 at 18:20
  • Yeah. That should have the desired effect. It is not the most elegant of solutions, but it still feels less intrusive than manually editing the `mailSender` properties yourself. – rmlan Dec 29 '14 at 18:27
0

I've realized this can be done accessing the mailSender bean from the context and updating it like is explained here

Changing mail configuration in runtime

However if @rmlan solution finally works it may be a much cleaner solution.

Community
  • 1
  • 1
Rafael
  • 2,521
  • 2
  • 33
  • 59
0

Actually thr rmlan solution works with the following fix. Since the onConfigChange compares hashCode of existing config map and new one, so if you set new configs in original configuration (Holders.config.grails.mail), then both configs are same and it never pass the condition to apply new changes, so a new structure should be created and pass it to notifyOfEvent method to mark the change as different hashCodes.

def mailConfig = [ grails: [ mail: [:] ]  ]

mailConfig.grails.mail.host = newHost
mailConfig.grails.mail.port = newPort

Holders.pluginManager.getGrailsPlugin('mail').
        notifyOfEvent(GrailsPlugin.EVENT_ON_CONFIG_CHANGE, mailConfig)

Still using async-mail and this one make the below exception

No qualifying bean of type [grails.plugin.mail.MailService] is defined: expected single matching bean but found 2: nonAsynchronousMailService,mailService

that is thrown because of the following part of onConfigChange

event.ctx.getBean(MailService.class).setPoolSize(mailConfig.poolSize?:null)

Commenting it let it works as a workaround, but making sendMail of mail plugin is called, not async-mail, so exception may raise if async-mail features is used on constructing mail. Hence to use async-mail in this workaround should use sendAsynchronousMail method.

Omid
  • 504
  • 1
  • 7
  • 14