Grails resources.groovy beans - grails

Im having some problems trying to actually determine if my beans have been properly loaded.
Is there some log4j property which can show me in the log what beans that are properly loaded?.
After some trying i went off and tried another example from here
redefining my resources.groovy like follows:
import grails.spring.BeanBuilder
BeanBuilder bb = new BeanBuilder()
bb.beans = {
ldapUserDetailsMapper(example.CustomDetailsContextMapper) {
}
}
CustomDetailsContextMapper in its turn is defined as:
class CustomDetailsContextMapper implements UserDetailsContextMapper {
def springSecuritySource
#Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection authorities) {
This is the error im getting when using this kind of resource.groovy setup:
2012-10-12 12:52:31,663 [main] ERROR spring.GrailsRuntimeConfigurator - [RuntimeConfiguration] Unable to load beans from resources.groovy
org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack: No such property: beans for class: resources
Possible solutions: class
When not using beanbuilder i get no errors but i cant really verify that my beans are loaded, since they seem never to be called.
In the other case i get the below error.
Any suggestions?

in resource.groovy simply write
beans = {
ldapUserDetailsMapper(example.CustomDetailsContextMapper) {
}
The BeanBuilder is already defined for you
A bean is called when used... inside a controller try thi
VeryBeanController{
def ldapUserDetailsMapper
def index = {
render( ldapUserDetailsMapper )
}
}
And call the controller

Related

How do you instantiate your own Validateable Object

I have a validateable object. When I instantiate it with new from an input Map, the ApplicationContext that should be embedded in the command object is not populated, and the invocaction fails when I call validate(), with the following Exception:
java.lang.IllegalStateException: Could not find ApplicationContext, configure Grails correctly first
What do I have to do to get a proper spring bean when I want to create a Validateable object and bind it to a Map of values?
Please note This code does not run in a grails controller: it runs in a rabbitMq consumer. So simple solutions applying to controllers will not work here.
class MyConsumer {
static rabbitConfig = [
queue : 'myQueue'
]
def handleMessage(Map message, MessageContext context) {
def request = new MyValidateableRequest(message) //instantiates just a POGO
if (request.validate()) { //Exception here
//...
} else {
//...
}
}
}
It depends on Grails version and if you use plugin for RabitMQ. Normally consumer should be a spring bean and you can use code like below. grailsApplication is bean which should be injected into consumer
def object = new MyValidateableRequest()
//do request binding here
object.properties = [message: message]
AutowireCapableBeanFactory acbf = grailsApplication.mainContext.autowireCapableBeanFactory
acbf.autowireBeanProperties object, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false
object.validate()
If you are on Grails 3, example which will not require plugin
https://spring.io/guides/gs/messaging-rabbitmq/ may be more interesting

Dependency injection not working inside Grails service

I have a class that I moved under the grails-app/services directory in order to inject the springSecurityService. This class is the implementation (Is that the proper terminology?) of the spring userDetailsService class. Here is my declaration in resources.groovy:
userDetailsService(com.company.product.PracticeUserDetailsService) {
grailsApplication = ref('grailsApplication')
}
This class is extending GormUserDetailsService.
My attempted dependencyInjection results in a null object.
class PracticeUserDetailsService extends GormUserDetailsService{
def springSecurityService
UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException {
// impl omitted
}
}
If I create some test controller or some service in grails and inject the springSecurityService, it works fine. So, there is perhaps something about this particular class that is not placing it in the Grails ecosystem. I checked out this to try to manually inject it as follows:
beans = {
springSecurityTEST(grails.plugins.springsecurity.SpringSecurityService) {}
}
Move PracticeUserDetailsService from grails-app/services to src/groovy and change your Spring bean definition in resources.groovy to:
userDetailsService(com.company.product.PracticeUserDetailsService) {
grailsApplication = ref('grailsApplication')
springSecurityService = ref('springSecurityService')
}
For me it happened when I used GrailsApp.run(Application, args) to run the app...

Set datasource values during run time

So essentially I'm trying to get my project up and running on AppFog. The datasource information is stored in an enviornment variable, which is essentially JSON. My goal is to take this data and set my datasource config from it.
Here is what I have tried:
Code to set the datasource config which is a method in a POGO. The POGO is instantiated and the method called at the beginning of DataSource.groovy:
import appfog.ParseDataSource
new ParseDataSource().setConfig()
dataSource {
...
}
class ParseDataSource {
void setConfig() {
String env = java.lang.System.getenv("VCAP_SERVICES")
if (env) {
def config = JSON.parse(env)
config = config["mysql-5.1"][0].credentials
grailsApplication.config.environments.production.dataSource.username = config.username
grailsApplication.config.environments.production.dataSource.password = config.password
grailsApplication.config.environments.production.dataSource.url = "jdbc:mysql://" + config.host + ":" + config.port + "/" + config.name
}
}
}
The problem is that grailsApplication is always null. I've tried registering a spring bean in resources.groovy:
beans = {
parseDataSource(appfog.ParseDataSource) {
grailsApplication = ref('grailsApplication')
}
}
class ParseDataSource {
def grailsAPplication
...
}
I've also tried getting it via Holders:
GrailsApplication grailsApplication = Holders.grailsApplication
Either way it is null so I'm not doing something right. Any ideas?
I think you are making this overly complex. Overwriting the grails config object while still in the process of building it would cause an order of operations issue that would make the code very fragile.
Simply setting the values directly seems more straightforward:
Datasource.groovy:
def configJson = JSON.parse(java.lang.System.getenv("VCAP_SERVICES"))
def mysqlConfig = configJson["mysql-5.1"][0].credentials
dataSource = {
production = {
username = mysqlConfig.username
// etc.
}
}
If you wanted to keep parsing in its own class for clarity's sake, make the values properties and read them in the dataSource block rather than trying to put them in the grails config object:
config parsing:
class EnvironmentConfigParser {
String username
String password
String url
EnvironmentConfigParser() {
def configJson = JSON.parse(java.lang.System.getenv("VCAP_SERVICES"))
def mysqlConfig = configJson["mysql-5.1"][0].credentials
username = mysqlConfig.username
password = mysqlConfig.password
url = "jdbc:mysql://${mysqlConfig.host}:${mysqlConfig.port}/${mysqlConfig.name}"
}
}
in Datasource.groovy:
def parser = new EnvironmentConfigParser()
dataSource = {
production = {
username = parser.username
// etc
}
}
You should be able to access grailsApplication the way you have injected in resources.groovy provided you are injecting the bean parseDataSource somewhere in your application in any artefact.
In your special case you need the bean to be available in datasource.groovy. You were instantiating the POGO which will not help you injecting grailsApplication to the POGO. On the other hand, you cannot actually inject the POGO to datasource.groovy like
def parseDataSource
because it(datasource) is a config object during bootstrap.
The best way remains will be to metaClass the pogo at BootStrap and make grailsApplication available to it. Burt has shown it here exactly that way.
I was also thinking whether BeanPostProcessor can be useful in this case but I am not sure whether config per environment will be achieved. But you can give it a try if it helps in achieving your business need. It generally goes like:
//src/groovy
import org.springframework.beans.factory.config.BeanPostProcessor
class DatasourcePostProcessor implements BeanPostProcessor{
def parseDataSource
#Override
Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean
}
#Override
Object postProcessAfterInitialization(Object bean, String beanName) {
if(beanName == 'dataSource') {
//Set values to dataSource bean as required
parseDataSource.setConfig(bean)
}
return bean
}
}
//resources.groovy
parseDataSource(ParseDataSource){
grailsApplication = ref('grailsApplication')
}
datasourcePostProcessor(DatasourcePostProcessor){
parseDataSource = ref('parseDataSource')
}

springSecurityService in resources.groovy grails file?

I'm having trouble accessing springSecurityService from resources.groovy file, I'm trying to load user locale setting and create LocaleResolver
import User
beans = {
localeResolver(org.springframework.web.servlet.i18n.SessionLocaleResolver) {
def user = User.get(springSecurityService.principal.id)
if (user?.settings?.locale) {
defaultLocale = new Locale(user?.settings?.locale)
java.util.Locale.setDefault(defaultLocale)
}
}
}
Thanks,
Mika
Your code above doesn't make a lot of sense. In resources.groovy you're supposed to define the implementation class of Spring beans and set their dependencies. It looks like you're trying to actually write the implementation class in resources.groovy.
Instead you should write your own LocaleResolver class
package org.example
class MyLocaleResolver extends AbstractLocaleResolver {
def springSecurityService
// implementation of methods omitted, because I haven't clue how you want to resolve Locales
}
Then in resources.groovy, define a bean of this type that replaces the default localeResolver bean
beans = {
localeResolver(org.example.MyLocaleResolver) {
springSecurityService = ref('springSecurityService')
}
}

Adding changes listeners in Grails' GORM

I'm new to Grails and I'm using Grails 2.0.1. I want to add a persistence event listener for changes in objects for a domain class, so I tried the code in Bootstrap.groovy as given in the user guide:
def init = {
applicationContext.addApplicationListener(new FooBarListener())
}
And I get the following error message:
ERROR context.GrailsContextLoader - Error executing bootstraps: No such property: applicationContext for class: BootStrap
How can I get the applicacionContext property from inside the BootStrap class?
or Is the documentation outdated and there is a new/better way to add domain changes listeners?.
Thanks in advance.
The shortest way I know is
class BootStrap {
def grailsApplication
def init = { servletContext ->
def applicationContext = grailsApplication.mainContext
}
}
import org.codehaus.groovy.grails.commons.ApplicationAttributes
class BootStrap {
def init = {servletContext ->
def applicationContext = servletContext.getAttribute(ApplicationAttributes.APPLICATION_CONTEXT)
}
}
applicacionContext must be defined in BootStrap. Following should work
class BootStrap {
def applicacionContext
def init = {
applicationContext.addApplicationListener(new FooBarListener())
}
}

Resources