Is it possible to create gant scripts to automate generalized processes.
e.g. Grails provides a default script 'create-app' to create a project using a tomcat container. Now suppose that I want to write my own script that could create projects using jboss as a server. I would like to save this script in a generalized manner so that I can use it to create more projects, rather than save it under some specific projet.
Is it possible to do that?
Yes, save it in $HOME/.grails/scripts. This way it will be available to all Grails installs.
Note that the naming convention is important; if the script starts with an underscore, it cannot be called directly as a script, only included in others (e.g. to store common code and methods). If it ends in an underscore, it can be called outside of a project (e.g. the create-app script is named CreateApp_.groovy). If there's no leading or trailing underscore then it can be called from within a project.
Related
I've got a Grails plugin that exports domain objects so that several applications can share the same schema. We have a few SQL scripts for setting up some complex triggers, views and other functions that just don't really belong in GORM/Hibernate, at least not elegantly. I'd like to store the scripts inside the same project. Is the "scripts" folder (the one containing _[Un]Install/Upgrade.groovy) the best place for this? I saw a StackOverflow answer that was building a catalog from scripts stored in grails-app/conf/sql. But I'm not actually trying to execute them from within the a project.
The absolute best solution for anything database related is to use the database migration plugin. This way you can ensure that any database your application is pointed to (dev, test, prod, etc.) will have the same information/schema/functions/procedures etc.
Personal preference. I usually add a 'database' dir for all that kind of stuff. The 'scripts' dir is for Grails scripts, at least in 1.x and 2.x. See Creating Gant Scripts or the create-script command for more on those. In Grails 3 these kind of scripts have been moved to src/main/scripts.
While using the DB Migration plugin I came across an interesting question. In our regular war deployments, time and again, we need to run certain scripts for data updates to accommodate our changed code. While we can still run these externally, we were trying to find a way to add them as a part of DB Migration process.
Now one set of these scripts can be converted into migration scripts and added inside the grailsChange section and and they run pretty seamlessly. There is another set of scripts though, which are problematic because of a couple of reasons.
These scripts are run time and again so we would have to keep changing the id with every run as we don't want to duplicate the code, thus losing the original changes.
We pass params to these scripts from the command line and by the method above we have to add them to the scripts themselves just causing maintainability issues.
So my question would be, is there a more elegant way to trigger external grails or groovy scripts from within the DB migration scripts such that every time we need to run a script file, we can create the changelog with the updated call and tag it with the app.
I think there was a post on stackoverflow regarding this a while back, but I cannot for the love of my life, find it any more. Any help regarding this would be appreciated.
Thanks
Are the scripts something you could add into bootstrap.groovy? That would probably be the simplest. Just use groovy.sql.Sql to run the scripts.
Another more functional and flexible option would be to create a service to run the scripts (groovy.sql.Sql) and a domain class to track the scripts that have been run. You could trigger the service in the bootstrap.groovy file and the service could look at some migrations domain class you set up to see if the script has been run. You could even go as far to secure a front end to this mechanism to upload a script file to execute at runtime.
Let me know more details of what you want and I can try to be more detailed in my response.
I have a sizable Grails application that has a small handful of controllers and views, and a very large number of Services.
I now need to build a "reskinned" version of the same site which has its own set of views and controllers (there are some smallish differences in how the controllers work), but the exact same set of Services. One option is to move all of the services into some kind of common place via custom Grails plugins, but I'm wondering if there's another way.
What I'd like to do is have two packages in the controllers folder, com.company.sitea and com.company.siteb, with an environment variable that effectively chooses which one of those is used. Similarly, two different sets of views, each one selected based on this environment variable, but with a shared taglib.
I was unable to find anything obvious that did this, is there a plugin or a standard way of doing this (or something similar)? The idea is, I'd have one codebase, I'd build one war, but the war would be deployed in two different places, and each one of those would specify a value for a special environment variable.
We have been successfully using a pattern where we make the first application a plugin. It will be run as an application for the first use case and included as a plugin to the second use case.
If you do this (a grails application is a application and plugin at the same time), you have to exclude the plugin from starting up when it's run as an application. Otherwise the application will start it self twice: as an application and as a plugin. The "grails.plugin.excludes" configuration setting (explained here) prevents this from happening.
I have documented this special use case in this jira issue:
http://jira.grails.org/browse/GRAILS-6751
"Allow a Grails application to be used as a Grails plugin besides using it as an application"
This has turned out to be a killer feature for us in many cases. We have been able to reuse applications as plugins in other use cases and combine several separate applications to one with this feature. Of course there are some restrictions (like name conflicts) but that hasn't been a problem for us.
The most common use case is to reuse a full application and just override the views in another one. Since an existing application can be an application and plugin at the same time, there is no extra work in extracting "common parts" to a separate plugin.
To make an existing Grails application a plugin you just have to add a MyAppNameGrailsPlugin.groovy file to the root directory and add this configuration value to grails-app/conf/Config.groovy:
grails.plugin.excludes = ['myAppName'] (application name in camel case starting with lower case letter)
Mailing list discussion:
http://grails.1312388.n4.nabble.com/Dynamic-applications-extending-an-existing-application-with-Grails-tp4634094p4634202.html
Burt's detailed blog post:
http://burtbeckwith.com/blog/?p=1973
David Dawson's presentation:
http://skillsmatter.com/podcast/home/large-scale-grails-using-plugins-how-to-modularise-an-application/jd-8012
one important factor is whether both of these versions should operate on the same data? so they will be different front-ends over same database? or they will be completely separate, for example per-customer deployment?
if the first, I would go webservices way, so one app would contain business logic, and controllers working as webservices, and other app would just have different controller, "talking" to the first one
you could also combine everything in one project (both versions) and limit access to different controllers from different domains with apache unmounts
if the latter, I would also try to extract common part into a plugin
We would like to use the Quartz plug-in persistent mode for working in a cluster. Our DB schema is maintained using the DB-migration plug-in, and therefore we can not use the provided SQL script for updating the DB.
Is there a db-migration script (i.e. - a Groovy file) that creates the tables, that we can use? Can someone that managed to run the migration share one with us?
Alternatively - is there another way to create the tables, when working in DB migration mode?
Thanks
Maybe instead of trying to convert the scripts you could use them directly by either considering this: http://www.liquibase.org/manual/formatted_sql_changelogs or this:http://www.liquibase.org/manual/custom_sql_file. I think you can use liquibase's include tag with the sql change log. Basically just copy and paste the contents and run them using one of the 2 methods I listed above. If you use the second method, maybe you don't need to copy and paste anything and just directly reference it?
I have a Grails Application AppA. And I am planning to create a new Grails Application AppB, wherein AppB practically uses the same services and models of AppA.
How should I approach that?
Extract a Grails Application AppC which would have the common services and expose that service as a remote/web/rest service?
Extract a Groovy project ModC that will be a jar containing the common services and models and have AppA & AppB depend on ModC?
Just git clone and cherry-pick every now & then?
Other suggestions?
Note that AppA have some lazy-loaded relationship invocations (i.e. entity1.entity2.entity3.propName) & GORM invocations (i.e. Entity1.get(1L)) from the presentation layer (controllers & views) as well. Although I can probably push some of them back to the services, I'm concerned about the refactoring effort to have the relationship invocations from the view remain intact (i.e. I would need to eager loaded some associations, or create Data Transfer Objects)
The Grails way to share common functionalities, utilities and whatnot is to make a plugin that encapsulates those and install it to both projects.
A plugin can contain anything you can put in a regular Grails app -- i.e. Models, Service, Views, Controllers, config files, resources under web-app etc.
You can then either release it to an internal svn repository or just use it with package-plugin
Edit:
One way to do it while you are constantly updating the code is to have it as an inline plugin. So remove the plugin from your application.properties and add:
grails.plugin.location."name-of-plugin" = "/path/to/plugin/dir" // or "../plugin/"
This removes the necessity of reinstalling the plugin all the time. But this is for development time only.
Have you considered the option of separating your models and services (the ones used by both apps) into a plugin. I think that is the prefered way at least from what I have been following within the community.
You can take a look at this link. It is not exactly equivalent to your case, but should give you a good idea for the plugin approach.
I had this situation on a previous project and we used a plugin project to hold our common functionality and it worked really well. I don't think a jar file would work well since as far as I know you wouldn't be able to take advantage of things like auto-wiring dependency injection of services, the domain/GORM/dynamic finders on domain objects, etc.
I think I would put the functionality into a separate jar and use it in the two applications (so your suggestion no 2). I wouldn't make a new application (suggestion 1) because you just need some services not a whole web application, and I wouldn't do suggestion 3 because the services wouldn't be as reusable as with suggestion 2.