Grails Beans - defining list of Values - grails

I need to add more than one XSD to my list of XSDs in this Grails Spring Bean :
springws {
wsdl {
Holiday {
wsdlName= 'Holiday-v2'
xsds= '/WEB-INF/Holiday.xsd'
portTypeName = 'HolidayPort'
serviceName = 'HolidayService'
locationUri = grails.serverURL + '/services/hr/v2/Holiday'
targetNamespace = 'http://www.myveryimportantcompany.com/hr/v2/definitions'
}
}
}
So I want to pass in more than one value to xsds ... how do I represent this in Groovy / Grails?
Thanks

I hope you are referring to springws plugin. You can use multiple schemas as below:
springws {
wsdl {
Holiday {
wsdlName= 'Holiday-v2'
xsds= '''/WEB-INF/Holiday.xsd,
/WEB-INF/Example1.xsd,
/WEB-INF/Example2.xsd'''
portTypeName = 'HolidayPort'
serviceName = 'HolidayService'
locationUri = grails.serverURL + '/services/hr/v2/Holiday'
targetNamespace = 'http://www.myveryimportantcompany.com/hr/v2/definitions'
}
}
}
You can refer this sample project for more details about the usage of springws plugin.

Related

Grails: Initialize variable using Configuration file

I just wanted to know that is it possible to set the value of a variable in Grails controller from the configuration file like config.groovy or some other configuration file?
For instance , my controller is as follows:
class WebsiteController {
def show(){
String user_name = "value to be fetched from configuration file"
}
}
Here, I want to set the value of user_name from the configuration file. I have no idea how to do this.
I have been given this requirement by my senior. I searched online but couldn't find anything relevant. If it is possible, please tell me the approach.
Thanks
Here is an example of properties added to the Config.groovy:
environments {
development {
tipline.email.address="joe#foo.us"
grails.logging.jul.usebridge = true
}
staging {
tipline.email.address="mailinglist#foo.us"
grails.logging.jul.usebridge = true
}
production {
tipline.email.address="mailinglist#foo.us"
grails.logging.jul.usebridge = false
// TODO: grails.serverURL = "http://www.changeme.com"
}
}
To access them in your code:
println("Email :"+grailsApplication.config.tipline.email.address)
Properties are properties =)
Properties properties = new Properties()
File propertiesFile = new File('test.properties')
propertiesFile.withInputStream {
properties.load(it)
}
def runtimeString = 'a'
assert properties."$runtimeString" == '1'
assert properties.b == '2'
Taken from Get values from properties file using Groovy
Another possibility is to inject parameters into the controller by using a property override configuration:
// Config.groovy:
website.user = "me"
beans {
'<replace by package>.WebsiteController' {
userName = website.user
}
}
// Controller:
class WebsiteController {
String userName
def show(){
//.. use userName ..
}
}
In this case you don't need grailsApplication and you don't hard code the configuration path in the Controller. Less dependencies make testing easier. :)

grailsuser MissingPropertyException

I am trying to use <sec:loggedInUserInfo field="firstName"/> and I am getting MissingPropertyException. I extended User and have in configured as below. I am not sure what I am missing...
resources.groovy
preAuthenticatedAuthenticationProvider(org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider) {
preAuthenticatedUserDetailsService = ref('preAuthenticatedUserDetailsService')
}
preAuthenticatedUserDetailsService(org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper) {
userDetailsService = ref('userService' )
}
userService(org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsService){
grailsApplication = ref('grailsApplication')
}
I also have my domain classes configured in Config.groovy
grails.plugins.springsecurity.providerNames = ['preAuthenticatedAuthenticationProvider' ,'anonymousAuthenticationProvider']
// Added by the Spring Security Core plugin:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'com.administration.AuthUser'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'com.administration.AuthUserAuthRole'
grails.plugins.springsecurity.authority.className = 'com.administration.AuthRole'

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')
}

Extending SpEL with own methods in Grails?

I'd like to add custom SpEL methods in Grails applciation, like it's done for plain Spring-Security application in this question, by overriding EvaluationContext. Will this work?
How do I plug global-method-security into security config? I can configure security, but what to add there? Something like
grails.plugins.springsecurity = {
'global-method-security' {
'expression-handler' {
ref("myMethodSecurityExpressionHandler")
}
}
}
? But what code will interpret it?
Looking into SpringSecurityCoreGrailsPlugin.groovy also gives me no insights.
This is only available if you also have the spring-security-acl plugin installed. It configures the expressionHandler bean:
expressionHandler(DefaultMethodSecurityExpressionHandler) {
parameterNameDiscoverer = ref('parameterNameDiscoverer')
permissionEvaluator = ref('permissionEvaluator')
roleHierarchy = ref('roleHierarchy')
trustResolver = ref('authenticationTrustResolver')
}
So if you have your own subclass of DefaultMethodSecurityExpressionHandler you can replace the bean in resources.groovy like this:
import com.mycompany.myapp.MyMethodSecurityExpressionHandler
beans = {
expressionHandler(MyMethodSecurityExpressionHandler) {
parameterNameDiscoverer = ref('parameterNameDiscoverer')
permissionEvaluator = ref('permissionEvaluator')
roleHierarchy = ref('roleHierarchy')
trustResolver = ref('authenticationTrustResolver')
}
}

Grails UrlMappings with parameter values containing "."

Given this UrlMapping:
"/foo/$foobar" {
controller = "foo"
action = "foo"
constraints {
}
}
Combined with this controller:
class FooController {
def foo = {
def foobar = params.foobar
println "foobar=" + foobar
}
}
And with these requests:
http://localhost:8080/app/foo/example.com give the output "foobar=example"
http://localhost:8080/app/foo/examplecom give the output "foobar=examplecom"
It seems like Grails cuts the "foobar" parameter at the first dot ("."). Is this intentional? Is there a work-around if I want to use parameters containing dots in my URL mappings?
This can be solved by setting ...
grails.mime.file.extensions = false
... in Config.groovy.
It seems like Grails is trying to do some MIME magic behind the scene based on the file name suffix.
Updated: Some additional info from the Grails JIRA.
This is the offending code in UrlMappingsFilter.java:
if(WebUtils.areFileExtensionsEnabled()) {
String format = WebUtils.getFormatFromURI(uri);
if(format!=null) {
MimeType[] configuredMimes = MimeType.getConfiguredMimeTypes();
// only remove the file extension if its one of the configured mimes in Config.groovy
for (MimeType configuredMime : configuredMimes) {
if (configuredMime.getExtension().equals(format)) {
request.setAttribute(GrailsApplicationAttributes.CONTENT_FORMAT, format);
uri = uri.substring(0, (uri.length() - format.length() - 1));
break;
}
}
}
}
WebUtils.areFileExtensionsEnabled() returns the value of the "grails.mime.file.extensions" setting configured in Config.groovy.

Resources