Create a custom scope for a Grails quartz job - grails

Has anyone managed to create a custom scope in Grails?
I did this in BootStrap.groovy (injected grailsApplication):
grailsApplication.mainContext.getBeanFactory().registerScope('simpleThread', new SimpleThreadScope())
And in my spring/resources.groovy, I have:
myContext(MyContext) { bean ->
bean.scope = 'simpleThread'
}
This then gets injected into all my domain objects.
This seems to work... but there are warnings about objects using SimpleThreadScope not getting destroyed... I am wondering if this is safe.
I do this because I can't use Request scope, because we fire off Quartz jobs (using the Grails plugin), and the request gets destroyed.
We use this context object in both regular web requests and async ones that use Quartz...

Related

Grails access domain data during service initialization

I am trying to implement a search service where i want to do some initial data caching when the service is created. The service implements the spring framework InitializingBean interface, but when I try to use the afterPropertiesSet method to get data from my domains, I get an error stating that GORM is not ready for use. Is there any way to have domain objects available for use in the afterPropertiesSet method? Grails 2.5.0.
I'm not aware of an event or something similar to notify when domain classes have been initialized, but it does happen before BootStrap runs. For cases like this where afterPropertiesSet is too early to do something, you can dependency-inject the service in BootStrap and call your own init method, e.g.
class BootStrap {
def myService
def init = {
myService.init()
}
}

asp.net 5 DI: Using scoped service outside request

We have a IOrderManager service which uses some other services registered in DI via AddScoped().
Now we need to use that service in the OnMessage handler for some queue which, obviously, is raised outside any request pipeline.
So when we try to get our service using something like
var orderManager = ServiceProvider.GetRequiredService<IOrderManager>();
we got "Can't access disposed object ..." exception.
Question: is it possible to "tell" DI that we are inside some "fake request" processing to avoid disposing services registered as "scoped"?
If your IOrderManager is outside request scope, you can create your custom scope per-message like this:
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var myService = serviceScope.ServiceProvider.GetRequiredService<MyService>();
}
If you're using scoped services within IOrderManager, IOrderManager needs to also be scoped.
If you don't do this, when the IOrderManager instance is first created, it will "capture" the scoped dependencies from the current request.
Any future usage of IOrderManager will continue to use the old scoped dependencies and not dependencies from the current request scope.
Next, the only reason you should use scoped dependencies is if they somehow maintain state across a single request and need to isolate that state from other requests.
If your IOrderManager doesn't actually need information that is scoped to a request, it shouldn't be scoped and shouldn't use dependencies that are also scoped.
Put another way, if you think it should be usable outside of an active request, it by definition is not scoped does not require scoped dependencies.

Grails Spring Security Expression - How to access Method parameter

Using the Spring Security Plugin for Grails:
Version: 2.0-RC2
For my controllers I am using the #Secured annotation.
Is there a way to access the method parameter from the spring security expression.#paramName does not work for me.
#Secured(['ROLE_ADMIN',"hasRole('ROLE_USER') && #permissionService.updateAllowed( #myInstance )"])
def update(Bug myInstance) {
The problem: myInstance is null!
Software I am using:
Grails: 2.4.3
Intellij 14
JDK 8
I didn't notice that you were doing this in a controller - there's no support for method args in annotated controllers. The reason for this is that in traditional Spring Security, the annotation is applied to Spring Beans and the bean becomes proxied, and the proxy does the security checks before calling the method and only calls the real method if the checks pass. That works well with Spring MVC controllers because they're regular Java classes, and also in Grails services because there isn't much added to services by Grails - they're really just regular Groovy classes that are auto-registered as Spring Beans, and by default are made transactional.
But controllers are weird. There is actually one SpringMVC controller in any Grails app, and it's internally created and used by Grails. It interacts with the rest of SpringMVC, and delegates to the controller that best matches the url mappings rule for the current request to do its work, and it uses that to create the ModelAndView that Spring expects. Additionally, to support databinding, there's an AST transform that runs on your code during compilation which creates a no-arg method for each method with args, and that is what is called from the Grails internal request handling code. It does databinding and type conversions, and calls the "real" method to handle the request.
The support in Spring Security for working with method args depends on debug information being available in the compiled code, and usually this is not available because it's rarely needed - javac connects everything for us at compile time and getting the value of a method arg from outside of the method isn't often needed. Grails does keep that debug info - that's why this works in a service - but it looks like the AST isn't. It might be possible to get that working, but I have no idea if it is or what would be involved, and to be honest it would likely be a lot of work for a feature that wouldn't be used a lot.
But you can rework the check to pass the params to the service and let it lookup the Bug instance and then do its check. You can access the params from the service, so there's no need to pass anything as args:
import org.springframework.web.context.request.RequestContextHolder
...
def params = RequestContextHolder.requestAttributes.params
I've managed to get a workaround for the problem described in the comments to the accepted answer. Use #this in SpEL expression:
#Secured('#securityService.userCanEditOffer(#this)')
def edit(int id) {..}
Then create such methods in your service:
def userCanEditOffer(WebSecurityExpressionRoot webSecurityExpressionRoot) {
UrlMappingInfo urlMappingInfo = Holders.applicationContext.grailsUrlMappingsHolder.match(webSecurityExpressionRoot.request.forwardURI.substring(webSecurityExpressionRoot.request.contextPath.length()))
userCanEditOffer(Integer.valueOf(urlMappingInfo.params.id))
}
#Transactional(readOnly = true)
def userCanEditOffer(Integer id) { .. }
Inside ulrMappingInfo.params you'll have id, action and controller!

CDI Keeps all Injected tree references of SessionScoped beans?

I am starting a new project with JavaEE 7 and declared a Sessionscoped bean to maintain the web logged user information in session.
The UserSessionBean, as I named it, is intended to be lightweight - trying to avoid lots of data to be kept in the session by Weld. But in some cases I need to get all user information, so added a getUser() method which must query and retrieve a UserEntity from JPA. In order for the method to do its job, I need to #Inject other resources onto the UserSessionBean.
My question is: These dependant resources will be kept and serialised within the UserSessionBean by Weld until the context is destroyed?
The weld documentation says this:
An instance of a dependent bean is never shared between different
clients or different injection points. It is strictly a dependent
object of some other object. It is instantiated when the object it
belongs to is created, and destroyed when the object it belongs to is
destroyed.
That makes me think the all SessionBean tree is kept by weld during session life, but how can I keep a lightweight SessionBean and use injected CDI resources on it?
Since what you're injecting are also CDI beans, it is not the beans themselves that get serialised, but their lightweight proxies. Upon deserialisation, the proxies dynamically resolve the correct beans for whatever scope they are. See section 5.4 Client Proxies of the CDI1.0 spec. Hence, your bean is as lightweight as possible.

Access to Application Context from Grails Filter Constructor

How can I access the Application Context from a Grails Filter. I am able to do so from a Controller by using the following:
def ctx = ApplicationHolder.application.mainContext
But in a Filter ctx is null.
In this case, I'm specifically trying to access the application context in the Filter's constructor.
You shouldn't use the holder classes - they're deprecated in 2.0 and will be removed in a future release.
The best way to access the application context from a controller, filter, service, etc. is to add a dependency injection for the GrailsApplication, i.e
def grailsApplication
Then you can get the context via
def ctx = grailsApplication.mainContext
It's unusual to do work in a constructor that's related to Spring beans, so if possible you should refactor. Grails artifacts are Spring beans, so they're instantiated while the application context is being constructed.
Controllers are a bit different since they're not singletons like most beans, so by the time they get constructed (one per request) the holders are populated. But in general you should avoid doing GORM work, accessing the application context, etc. in a constructor since it's unlikely that things are wired up yet.

Resources