Common backend Grails application - grails

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.

Related

Is there a Grails 3 profile for creating a batch application?

I'd like to create a batch application that has GORM hooked in, etc. Is there a Grails 3 profile for creating a batch (not web) application? Is there some other pattern for using Grails/GORM in a batch context?
EDIT: None of the profiles with 'grails list-profiles' would seem to apply. I've not had luck searching for how to do this, so maybe no one uses this pattern and uses a simple Gradle build instead.
If you want to use the GORM outside grails, I suggest you check the latest GORM documentation. You can creeate a simple groovy app and receive information from the command line and use the GORM functionality inside of it.

Where is the appropriate place for SQL scripts in a Grails project

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.

Grails: Two Sites, One Codebase

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

Create a Glassfish 3 domain as part of ant build?

I have a JEE6 project based on Glassfish 3.1.1 that is moving beyond the "one developer prototype" stage to being developed by a team.
Each member of the team will have their own local glassfish server. I don't want each of them to have to go through all the manual steps of setting up the JDBC connection pool, JMS services, jdbc security realm, etc via the admin console, as I did when first developing the prototype. It is error prone, and plus if I want to change something I have to tell everyone what to do. I want it to be done as part of the ant build, so that it is a one-clicker, and then if I have to change something I can just tell them to do a clean to blow away the domain and then run it again. So there would be an ant task to "config-glassfish" that would somehow configure the domain for them.
Despite extensive searching, I can't seem to find any step-by-step guide of how best to accomplish this. Anyone have a link?
Would it be best to attempt to capture the fully configured domain and store that in our src repository?
Or should I instead have ant issue "asadmin" commands to create and configure the domain?
You can do all of this with the sun-appserv-admin ant task. You can find more information here: http://docs.oracle.com/cd/E19316-01/820-4336/beaev/index.html
We struggle with this kind of thing at my work too, but only with a few developers. One thing I really like is that Glassfish has the concept of a resources.xml which will cover a lot of the config. I use this to pass around connection pool configs and JMS queues and it works really well, but it might not cover all your config needs. The contents of the file are pretty much snippets from the domain.xml, and I haven't figured out everything it can do yet. http://docs.oracle.com/cd/E19798-01/821-1751/ggoeh/index.html http://javahowto.blogspot.com/2011/02/sample-glassfish-resourcesxml.html
I haven't tried other ideas since the resources.xml solves my major pain points, but you could take your domain.xml and work through any issues brought up by copying it to another developer's domain, then do variable replacement on the part of the file that need it. That way you could have ant create the domain, then overwrite the domain.xml with the newly filled out one.
Maybe there is a way you could use asadmin backup-domain
One other idea would be Chef. http://wiki.opscode.com/display/chef/Home
I ended up just putting the domain.xml into the src repository, making an ant task to copy it over to the glassfish directory, and instructing other developers that when running that ant task, they should make sure glassfish is not running.
This worked for my case...

ASP.NET MVC and multiple environments

How does ASP.NET MVC, if at all, deal with or provide ways to create your application using multiple environments? For example:
Development environment (local machine, probably run via the built-in web server and talking to a local database)
Testing (runs against a preloaded databse with example data, although this part could be skipped and mocks could be used)
Production database on a real server with real data
Ruby on Rails has the concept of environments and "automagically" can deduce if you're in development or production, so you can specify your connection information (connection string) in a config file and the framework dynamically pulls the appropriate one. Is there a similar way of doing things with .NET MVC? If not then how are professional developers using .NET MVC handling different environments?
The only way I can think of is to manually add an "environment" global method (or use an enum, or something like that, maybe this is a use for something like the State pattern?) and store the different connection strings in the web.config file, and then create a base class which all data access classes derive from which provides a way to obtain the connection string for the current environment; this would then have to be set to production when the time comes to put the application live.
Is there another way? Most of the .NET MVC videos and articles I've seen don't even bother with separate environments but only use a development database and don't indicate how you do it in production.
I'd say this is really a question of your company's internal processes. Since every company is a little bit different it's hard to have a "right" generic way to support dev/test/alpha/production and/or other environments.
One way: Create a setup program that supplies the correct connection string based on the environment chosen during the setup process.
Another way: System Admin edits web.config file to supply correct connection string during install.
Yet ANother Way: Connection strings are stored in the system registry.
Even Another Odd Way: You have all your connection strings for all environments in web.config, then a setting in appSettings the tells you which one to use.
Depending on the client, I've done all of these. There are more but these are the more popular.
(One client wanted to store the connecting string in the data base itself. Really.)
You can use alias for your database. You just point these aliases to different servers in the different environments. Stored in the registry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\Connect if i remember right. Then you use the alias in the connectionstring.
In response to Jason's response:
We use Enterprise Library Environments to configure the different environment paramters and via msbuild invoke the Merge Configuration Tool that generates the different configs for each environment. The deploy process picks the right config file depending on which environment to install.
I was able to solve a similar situation following these steps:
In your Visual Studio, access Build > Configuration Manager
Click in "new"
Choose a name for your configuration, and then copy settings from an existing config. After the configuration creation, it will be available for you to target as build configuration
Create a Web.{env-name-you-chose}.config in your application folder, along with the original Web.config file.
Open your .csproj file with Visual Studio or any text editor
Search for a section that looks like the following and add the highlighted lines, with the config file name you gave previously:
Open your Visual Studio, reload projects if it's required, and now you are able to choose your configuration via CLI or manual publish using Visual Studio.
There is a Publishing Wizard (in Visual Studio) wich let's you change parts of web.config for release build automaticaly. Wich happens to be the feature you are asking about. No magic thou.
What we have done is during our automated build process (Hudson), we alter values in web.config depending on which environment the build is for. Unfortunately there isn't a magical way to do this.
For deployment, which I assume that is what the op was asking about, one creates multiple configurations and in the publish, picks a different configuration. These are called transforms and they operate on the web.config. One would have at least three publish profiles, one for dev, test and prod. One can change more than just the connection string in this way. One can turn on custom errors, turn off debugging and change values of configuration variables. I highly recommend it.
I have a similar question. I have a log table reader. I want it to read log tables in the development, test and production databases. The major difficulty lies in my user account doesn't have permission to look at test and production. It's some silly security thing. The user that I'm impersonating in the application does have permission. I'm struggling trying to tell MVC to build the test and production models using the impersonated user.

Resources