in my grails application i'd like to invoke from a scheduled job class a method contained in a controller.
Reading this [http://www.grails.org/Job+Scheduling+(Quartz)], I can see that datasources and services are auto-wired by name in job classes. It seems this is not possible for controllers by default, probably 'cause controllers aren't supposed to do this kind of stuff.
BTW, is there a way to get a controller method called from a job in grails?
And could this be such a bad practice to you (and why)?
Thanks in advance,
Luca
It's bad practice because Controller is intended to handle web requests - with user session and everything.
There is no user session in Quartz job.
Second, keeping functionality in Controller is bad thing on its own - Controller should better only "control" invocations to other business logic method.
I'd recommend you to move all the functionality to either a service, domain class or a POGO class in src.
Of course, you can call new MyController().method(), but no beans will be injected into controller by default.
Related
I've not looked at the AutoMapper source code yet but was just about to make some changes to an API controller in my solution and had a thought.
The way I like to code is to keep my controller methods as concise as possible, for for instances I make use of a generic Exception attribute to handle try{}catch{} scenarios.
So only the code that is absolutely relevant to the controller action is actually in the action method.
So I just arrived at a situation where I need to create an AutoMapper map for a method. I was initially thinking that I would add this (as I have done previously) to the controller constructor so its available immediately.
However, as the controller grows following this pattern may introduce a lot unnecessary AutoMapper work depending on the controller action method which is invoked.
Considering controllers are created and destroyed per request this could get expensive.
What are some recommendations around this? Considering AutoMapper is accessed statically I was wondering if it's internals live beyond the request lifetime and it internally checks for an existing map before creating a new one each time CreateMap() is invoked?
You should create your maps (CreateMap) once per AppDomain, ideally when this domain starts (Application_Start).
I'm a java developer and got to work with a legacy Grails application. I have a controller class and a number of java classes. The controller has methods to start/stop tasks described in java classes. I'm using a ScheduledExecutorService for that.
The problem is that each time application is redeployed I have to call http://application/controller/start to make it initialize the scheduler. I want this controller.start() method to be called once when te app is launched. How can I achieve that or is there a better way to do this?
I would suggest to put this method in a service. You can call the service both from controller and from Bootstrap.groovy after application starts. You can also use standard #PostConstruct on service to start the process.
Your business methods should be located in services not in controllers.
If you really need to use controller, try this from Bootstrap.groovy:
new Controller().start()
I don't have env to test it but there shouldn't be a problem with it.
I'm trying to decide, according to Grails best practices and MVC patterns, when is the correct time to introduce a Service and not keep fattening controllers. I find it somewhat conflicting, what I've read about best practices and what appears to be common practice, so would love to hear what others think about this.
With GORM calls in mind, I would have expected that anything to do with GORM should really go into a service. Although I don't practice this myself, especially when writing very basic controller methods like show that simply perform a get() on a domain class and then render a view to show the details of the retrieved object.
However, after following books like 'Clean Code' and similar books, well maintained code should be cohesive and methods should ideally perform a single task only. So in the perfect world, would the show method in a controller be responsible only for determining the object to display before rendering a view? The retrieval from the database could go into a method in the database that's sole task is to retrieve from the DB and throw an exception if not found etc.
But yes, this does somewhat seem like overkill.
So taking the step a bit further, the create() or update() methods. Again currently Grails' generated code puts everything into the controller, no use of a service at all.
So when would the recommended point be that we need to use a Service? Is it only when something transactional has to take place, for instance, on a create() call, we might also want to write a record to a Log file to keep an audit log of sorts. Surely this warrants a service?
I'd love to hear what others feel is the correct time to introduce services, I imagine it differs greatly person to person.
I recommend you this post: http://www.infoq.com/articles/grails-best-practices
We are creating static methods in Domain class to encapsulate queries. Service are used only for transactional operations or very complex queries with multiple domains interaction. Controllers simply call domains or services methods.
I have an ASP.NET MVC application with a controller that looks something like this:
[Authorize]
public class MyController : Controller
{
IMyRepository myRepository;
public MyController(IMyRepository myRepository)
{
this.myRepository = myRepository;
}
...
}
I have noticed that this constructor gets called prior to authenticating the user, so if you are visiting the page for the first time the constructor is called prior to redirecting you to the login screen. There are many problems with this, the login page loads slower, the site has greater exposure to DOS attacks, and I'm a little nervous about unauthenticated, unauthorized users being able to invoke code 'behind the walls' sort of speak.
I could check the incomming request in the constructor and bail unless the user is authorized, but I'm using IOC (Windsor) which makes that a bit tricky, my repository is going to be initialized regardless of whether or not I store the instance, so I'd be left checking authentication in each repository's constructor. Is there an easy way to get .NET MVC to authenticate the user prior to invoking the constructor? I'm thinking something like adding [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] to the controller, but there might be a better way still.
EDIT:
Ok, not too happy about it, but the show must go on for now. I cannot delay initializing the repository until some later point in time from within the controller. When your controller uses IOC as in my example, you get an already instantiated implementation of your repository interface at the time that the controller is instantiated. If I had control over the repository being created, I could easily just call IsAuthenticated, no need for a new method. In order to take control of the repository initialization you would have to implement some sort of lazy/late initialization in the repository itself in each implementation. I do not like this solution because it adds needless complexity and more importantly coupling between the controller and repository. The repository implementation(s) may be used in other contexts where lazy initialization doesn't make sense IMHO.
The controller needs to be instantiated before authorization happens because it can act as its own authorization filter via the OnAuthorization method. Changing that behavior would involve replacing some core parts of the mvc pipeline. Is there a particular reason why you think the AuthorizedAttribute might not do its job?
Another option you could consider is initializing your repository in the OnActionExecuting of your controller method instead of in the constructor.
You can use HttpModules (or HttpHandler) to authenticate the request earlier in the pipeline.
MSDN: Introduction to HTTP Modules
MSDN: Implementing Intercepting Filter in ASP.NET Using HTTP Module
EDIT
With the introduction of OWIN you can configure the entire request pipeline middleware and put authorization at whatever stage you want. Same idea as above but a bit easier to implement.
Paul,
the instantiation of the controller is many many processes ahead of any actions on the controller being callable. even if the would be attacker attempted to benefit from this time lapse between instantiation and the login-screen, the controller action would only be able to run if the action had the authority to do so i.e. i'm assuming that your actions or controller all have the [Authorize] attribute on them.
I don't think you need worry too much about this and can rest easy, tho' i understand your obvious curiosity.
In terms of DOS attacks, it really should not matter -- after the first hit, which one sees alot when developing, the controller instantiation should be cheap. Well, unless you are DDOSing yourself by having the constructor do actual work such as pre-caching database lookups . . .
Documentation says:
The Grails team discourages the
embedding of core application logic
inside controllers, as it does not
promote re-use and a clean separation
of concerns.
I have one API controller and a few Groovy classes in src/groovy folder. Those classes just implements my application logic so actions in API controller works in this way:
//index page
def index = {
render new IndexApi().index(params) as JSON
}
I'm curious - is there any reason to move my application logic from plain groovy classes into services ?
Actually services are not just about transactions. Services are great for zero-config injectable singleton components, and they can can be reloaded without restarting the whole grails environment, AND they can be discovered as artefacts and hence automatically exposed with remoting plugins.
If you want transactional behavior you should put your logic in the Services. Else you would have to take care about it yourself, which is not in the spirit of using Grails.
Being not a grails expert myself, I put my 'not transactional' classes outside the service layer, like builder classes, helpers, and other logic that is not transactional but used from the service layer.
There are three reasons:
It makes the controller smaller -> easier to understand and maintain
It makes you logic easier to test.
You really don't want to manage your transactions manually.
If you would put everything in the controller, you would need to create the Web runtime to be able to run any test. If your logic is outside, you can copy the data you need from the HTTP request and all the other sources and just call the code. So the logic isn't depending on HTTP sessions, requests or anything else you don't want to.
For example, to test JSPs, you need a HTTPRequest. For a request, you need a HTTPSession and a JSPWriter. Those need a session context. So just to be able to run a single test, you need to set up and initialize a whole bunch of classes. And all of those are interfaces and the implementations are private. So you must implement the actual methods (all 300 of them) yourself. And you better get this right or your tests won't test what you want.