using GrailsApplication in service - grails

So I have done a bunch of research on using grailsApplication in services but none of them seem to work (2.4.4)
here's how i'm trying to use it
class AddressLookupService {
def grailsApplication
def addressLookup(address1, address2, city, state, zip){
def addressValidationErrors = verifyAddress(
grailsApplication.config.uspsUserId,
address1, address2, city, state, zip, '')
return addressValidationErrors.errDescription
}
}
and the error I'm getting
Cannot get property 'config' on null object

You can import Holders class in service as
import grails.util.Holders as H and then use this holder as
H.grailsApplication?.config?.uspsUserId

Related

createLink in ApplicationTagLib from service

I am trying to learn about creating the link using createLink from ApplicationTagLib called from the service.
Grails : 3.2.8
Code :
def applicationTag = new ApplicationTagLib()
def abc = application.Tag.createLink(controller:"accomodate", action:"menu", id:4)
Error :
org.grails.taglib.GrailsTagException: Tag [createLink] does not exist.
No corresponding tag library found.
I am very new to this version. I will be really thankful if you help me in finding out what sort of mistake is my code having.
try this:
import grails.core.support.GrailsApplicationAware
import grails.core.GrailsApplication
import grails.web.mapping.LinkGenerator
class MyService implements GrailsApplicationAware{
GrailsApplication grailsApplication
def config
LinkGenerator grailsLinkGenerator
def myMethod() {
def url = hostname+grailsLinkGenerator.link(controller: 'someController', action: 'something', params:[token:something], absolute: 'false')
}
void setGrailsApplication(GrailsApplication ga) {
config = ga.config
}
}
...
String hostname=grailsApplication.config.myApp?.hostName
def url=hostname+grailsLinkGenerator.link(controller: 'someController', action: 'something', params:[token:something], absolute: 'false')
or
def url=grailsLinkGenerator.link(controller: 'someController', action: 'something', params:[token:something], absolute: true)
ED2A
If you must
I have applicationTag lib working this way:
import grails.util.Holders
import org.grails.plugins.web.taglib.ApplicationTagLib
class SomeService {
def g = Holders.grailsApplication.mainContext.getBean(ApplicationTagLib)
def someMethod() {
def aa = g.createLink('something')
}
}
The problem with doing things this way is if you start hitting presentation layer references then you may get No thread-bound request found. Specially from quartz jobs and anything that is called outside of the scope of a real user. You can get around all of this using this example. But why go through all that when the grailsLinkGenerator example above won't hit any of the issues that may arise otherwise
I came here because I just wanted a link created in a regular service class, and V H's answer^ helped me; thank you! :D
But for those looking for the same thing I was, this is what is sufficient for us to work (Grails version 4.0.4):
import grails.web.mapping.LinkGenerator
and in the service method:
def link = grailsLinkGenerator.link(
controller: 'controlerName',
action: 'actionName',
params: [uuid: "uuidExample"]
)
Thank you once more, V H! :)

Grant role to "class" in spring security

Here's a (fictive) structure (sorry, I know I don't have a strong imagination) which to resembles the structure of my application:
(Person, SuperPerson and NormalPerson are abstract):
I'm wondering if I can grant roles to each class (so all the instances of this class will get these rights) using spring security in Grails.
No, Spring Security grants roles at the instance, not class, level.
There are two ways to grant authorities (permissions):
Grant them directly to a principle (user)
Grant them to a group (role), and then add principles to the groups containing the authorities then need.
So in your case, you can take the role-based approach and have each class represented by a role. Then, when you create an instance of a class, add it to the appropriate role.
Example of using a service to grant authorities
class PersonService {
private Map authorityGroups = [
Person: ['Person'],
NormalPerson: ['Person', 'NormalPerson'],
Employee: ['Person', 'NormalPerson', 'Employee'],
...
]
Person create(Class klass, Map props) {
def person = klass.newInstance(props)
def groups = getGroupsForClass(klass)
person.save()
groups.each {
new PersonAuthorityGroup(authorityGroup: it, person: person).save()
}
}
private Collection<AuthorityGroup> getGroupsForClass(Class klass) {
authoritiyGroups[klass.simpleName].collect {
AuthorityGroup.findByName(it)
}
}
}
The service can then be used like this:
def a = personService.create(Person, [first: 'John', last: 'Galt'])
def b = personService.create(SuperPerson, [first: 'Jane', last: 'Smith'])

Grails GORM MissingMethodException

new to groovy and stuck on this for quite some time.
Heres the method in question.
protected User currentUser() {
def user = springSecurityService.currentUser
println "In currentUser Method"
println "Is userId null?"
println user.id == null
println user.id instanceof Long
User.get(user.id)
}
And User.get is a method in the GORM package
D get(Serializable id) {
execute({ Session session ->
session.retrieve(persistentClass, id)
} as SessionCallback)
}
Im getting the error
No signature of method: User.get() is applicable for argument types: () values: []
What I dont understand is that through the println statements I verified that
user.id is not null
user.id is instanceof Long , which implements the Serializable interface.
Any idea whats happening here?
Thank you.
A possible solution could be that you have an invalid import statement. User is a very common class name so maybe you (or your IDE) have imported a different User class than you expect. The imported class might not have a get(id) method.

Spock test cases doesn't make a relationship of domain classes in Grails?

I have a Spock test case, in which the setup block looks like this :
setup: "set the required objects"
def company = new Company(shortName:"infyyy",fullName:"infoysys",
region:"tamilnadu" ,email:"a#ac.com" ,telphone:34343433,fax:34343433).save(failOnError:true)
def project = new Project(name:"testing")
def userInstance = new User(username:username,password:password,
company:company,project:project,pt:["dummy"]).save(failOnError:true)
def tasksInstance = new Tasks(title:"testingwork",startDate:(new Date()-4),endDate:(new Date().clearTime()-6),description:"blah blah",project:project,completed:true,user:userInstance).save(failOnError:true)
And more over, the Tasks domain class looks like this :
class Tasks {
static belongsTo = [ user : User, project: Project ]
//other code
}
And User class is like this :
class User {
static hasMany = [ holidays : Holiday, tasks : Tasks, pt:String, project: Project ]
//other code
}
But when I run my test and my test fails(not with an error message, but it fails in the then block of my Spock test) and I find a error in it. My setup doesn't create any relationship between User and Tasks, which makes my test to fail.
The controller code, which I'm trying to test is :
def todaysTasks() {
def user = User.get(springSecurityService.principal.id)
def choice = params.managersProject
params.max = Math.min(params.max ? params.int('max') : 10,100)
def search = Tasks.createCriteria().list(max: params.max as Integer, offset: params.offset as Integer, order: params.order as String, sort : params.sort) {
and {
project {
like('name',"${choice}")
}
eq('endDate', new Date().clearTime())
}
}
println "todays task selected project is " + search
[tasksInstanceList : search, tasksInstanceTotal: search.getTotalCount() ]
}
The println in the above test prints 0. Why does this happen even though I'm making the endDate in my test less than today's date?
Thanks in advance.
As far as I know, GORM does not auto-populate relationships, by following a belongsTo relationship.
I always do the following.
def u=new User(...)
u.addToTasks(
title:"testingwork",
startDate:(new Date()-4),
endDate:...
)
u.save()
Note that I have not created a task object. I have passed the Map of values directly to addToX... this emphasizes that the added object belongs to User and should be instantiated and saved by GORM.
You cannot (and you shouldn't) test criteria queries in your unit tests. Criteria queires are not supported in grails (and spock) unit tests. Read this question for possible solutions.

Simple model.. worth making an in memory class or just put it in the Database?

Sorry for the bad title, I've no idea what to call this question.
I have a simple class which basically just wraps an array and provides some custom access metods for it. Essentially all it stores is an array of doublets, each one holding a property type and it's uid.
My idea is that because this is such a simple usage, I can get away with just building this class and holding it in memory rather than generating a model and suffering the overhead of ActiveRecord (that may not be much, I'm not sure).
I'm worried I'm overthinking and I should just put it in the DB and forget about it?
class PropertyType
extend Enumerable
TYPES = [
['Site', 'Site'],
['New Home', 'NewHome'],
['Terraced House', 'Terraced'],
['Detached House', 'Detached'],
['Bungalow', 'Bungalow'],
['Townhouse', 'Townhouse'],
['End of Terrace House', 'EoTHouse'],
['Semi-Detached House', 'Semi-D'],
['New Development', 'NewDev'],
['Apartment', 'Apartment'],
['Duplex', 'Duplex'],
['House For Sale', 'House']
].freeze
def self.each
TYPES.each{|type| yield(type[0], type[1]) }
end
def self.convert_to_name(uid_to_lookup)
return if uid_to_lookup.blank?
TYPES.each{|type| return type[0] if type[1] == uid_to_lookup }
end
def self.convert_to_uid(name_to_lookup)
return if name_to_lookup.blank?
TYPES.each{|type| return type[1] if type[0] == name_to_lookup }
end
def self.each_uid
TYPES.each{|type| yield(type[1]) }
end
def self.each_name
TYPES.each{|type| yield(type[0]) }
end
def self.uids
TYPES.collect{|type| type[1]}
end
def self.names
TYPES.collect{|type| type[0]}
end
end
I think your class is fine, but personally I'd still put it in the database, just so I have an easy option for building an administrative interface for property types and letting someone else manage modifications to them over time.

Resources