Generate view for external model with Grails

If you like me are using a legacy domain (java / JPA) model with grails you might have encountered the question, how to do I use the grails view generation scripts? You cant just write : 

grails generate-views domainclass

Grails will not recognize domainclass as a domain class instead you need to specify the whole package path as well:

grails generate-views my.project.domain.domainclass

and voila! Grails will generate the views for you.

 

Mocking closure with Groovy in Spock

I recently found my self in a pickle needing to verify arguments passed into a Groovy closure (to be precise it was the sendMail closure in the Grails MailService plugin). The solution was to use a Expando add a sendMail closure onto it and point all argument closures to it as well. This way I could fetch a reference to the Map passed into the body closure. Se details below..

def "A remind me request shall send an email with the users email embedded within links"(){

        given: "a mail service"
            def mailService = new Expando()
            mailService.sendMail = { callable ->
                callable.delegate = mailService
                callable.call()
            }
        and: "a closure"
            def model
            mailService.to = {}
            mailService.subject = {}
            mailService.body = {Map map ->
                model = map["model"]
            }

        and: "the remind me service"
            def service = new RemindMeService()
            service.mailService = mailService

        and: "a user"
            mockDomain(UserImpl, [user])

        and: "a action with a correct email"
            def action = new RemindMeAction("tester@test.com")

        when: "service is invoked"
            service.remind(action)

        then: "mailservice shall be invoked with links containing users email"
            model["iphonelink"].contains(":tester@test.com")
            model["weblink"].contains(":tester@test.com")

        where: "there is a user which has such an email"
            user = new UserImpl(email: "tester@test.com")
    }

Spock

After practicing TDD (with emphasis on driven) for aprox. 3 years now I recently encountered Spock. I really starting to like Spock since it adds a readability and recurring structure to the tests. We can all agree upon that it is just as important that the test code is well written as that the production code is well written. This since the tests are the specifications of the system.

Before I found Spock the way I wrote my test mostly looked the same however to ofter I found it hard to understand what or how the test tested, coming back to the test code. Spock seem to give us a nice structured way to write our test in a way that it is readable what the code test and how it test. Spock runs on Groovy wich enables it to have functions / closure which i can be named by a string this enables us to write out test name as a sentence. Moreover Spock tests (or specifications as they are called in Spock lingo) are all structured in the sections given: -> when: -> then: -> where:.

given:
This section is somewhat like the unit test setup method.

when:
This section is where you invoke the code under test i.e. the playback phase.

then:
This section is where you write your expectations.

where:
This section is where you provide your test data.

Putting all this together gives us more readable test with a few comments test will become a few sentences which describes what and how the test test. Given the test below it could now be written as

“Given a mail service and a closure and the remind me service and a action with a correct email. When service is invoked then mailservice shall be invoked with links containing users email. Where there is a user which has such an email.”

def "A remind me request shall send an email with the users email embedded within links"(){

        given: "a mail service"
            def mailService = new Expando()
            mailService.sendMail = { callable ->
                callable.delegate = mailService
                callable.call()
            }
        and: "a closure"
            def model
            mailService.to = {}
            mailService.subject = {}
            mailService.body = {Map map ->
                model = map["model"]
            }

        and: "the remind me service"
            def service = new RemindMeService()
            service.mailService = mailService

        and: "a user"
            mockDomain(UserImpl, [user])

        and: "a action with a correct email"
            def action = new RemindMeAction("tester@test.com")

        when: "service is invoked"
            service.remind(action)

        then: "mailservice shall be invoked with links containing users email"
            model["iphonelink"].contains(":tester@test.com")
            model["weblink"].contains(":tester@test.com")

        where: "there is a user which has such an email"
            user = new UserImpl(email: "tester@test.com")
    }

dev@Cloudbees, Jenkins, Grails & GWT

Today I finally got my Grails  with the GWT plugin built with help of dev@cloudbees. It took some tinkering about, here is what I did.

The first issue was to setup jenkins to build a Grails app. There is a jenkins plugin that enables this however that plugins needs to be installed and enabled. To do this navigate to Jenkins Builds -> Manage Jenkins -> Manage Plugins. Look among the plugins under the “Available” tab (if not there, it might already be installed and should thus be under “Installed”) look for “Jenkins Grails plugin” and enable it (might require that jenkins is restarted). Jenkins Grails plugin

Then we should create a new job navigate to Jenkins Builds -> New Job. Name your job and choose “Build a free-style software project”. In the configuration form specify your SCM settings under the Source Code Management section, then look for the “Build” section. Click on the Add build step and choose Build with Grails. In the new section that appears fill in the Grails version you use, under Targets fill in the Grails command you wish to execute (ex. “prod war”) do not forget to enclose it in double quotes. Click save! If you only have a vanilla Grails project to build you are done here. Though if you use the GWT plugin and aim to build the GWT code as well there are some steps left.

The Grails GWT plugin depends on a GWT install directory and does so by the usage of the environment variable “GWT_HOME”. To support this in Jenkins we need to install one more plugin. To do that navigate to Jankins Builds -> Manage Jenkins -> Manage Plugins look under available plugins after “Hudson Setenv plugin” and enable it. Now we also need to make the GWT install directory reachable by the build environment. This can be done by uploading it to you private repository in cloudbees. You should have three different repositories available namely a “private”, a “release” and a “snapshot” repository these can all be mounted as webdav drives. Mount your private repository and upload your GWT install directory into it (you should note that a GWT installation is quite heavy aprox 300MB however that is with all java docs and example projects etc. Those should be left out, you shall only upload the .jar files from the installation directory.). Now navigate back to Jenkins Builds -> Click on your job you previously created -> Configure. In the configuration form look for the “Build Environment” section, check the “Set environment variables” and enter “GWT_HOME=/private/username/my-gwt-folder” were username should be the login you use to access cloudbees and my-gwt-folder should be the name you gave the folder which you placed all GWT .jar files into in the previous step. Voila! your are setup to build your Grails / GWT project in Jenkins on Cloudbees.

ShareKIT and authorize#error error unknown

Have you encountered this error when you try to share to facebook with the sharekit API? Then it might be that you have not entered the App ID (see facebook api) correctly. In my case I did not understand that the hash att the start of the App ID should be included. I only entered the App ID like so: “com.mydomain.myapp” however your App ID should look something like “adflkg.com.mydomain.myapp” where the “adflkg” is the part I forgot.

HTML 5 cache manifest and NETWORK: section

If you experience problems when using the application cache feature (in the HTML 5 spec.) and online javascript. It is probably because you need to specify a NETWORK: section within your manifest file. This specifies the resource you expect to only work online (in my case google maps api). I thought that everything not specified in the manifest file would be treated as online resources. However as it turns out resources not specified in neither the CACHE: nor the NETWORK: section will / can behaive strange. To solve this in one blow just add a “NETWORK:*” section in your manifest file.

CACHE MANIFEST
#Version 1.1
CACHE:
myoffline_javascript.js
NETWORK:
*

Struts 2 build versioned css

A common problem a web developer faces is the way browsers cache css files. If not handled properly the end user could get a rather funny looking web page from time to time depending on how often the web page changes styling.

A way to circumvent this is to rename the web page top most css file each time the styling is changed. In a distributed development team it can easily get cumbersome to coordinate the renaming of the css file so that referring css links not get broken. Another issue with renaming of files in a development team (using any kind of versioning system) creates a lot of noise in the commit log.

If you are using maven as your compile agent there is a nice way to write the build version into the WAR MANIFEST file.


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-war-plugin</artifactId>
<configuration>
  <warName>minvolvo</warName>
  <archive>
   <manifestEntries>
     <Implementation-Version>${project.version}-b${build.number}</Implementation-Version>
   </manifestEntries>
  </archive>
 </configuration>
</plugin>

Having the version number in the manifest file you can use that version number to fool the browser that we change the css file name on each build.

Create logic which can read the version number from the manifest file.


public class ManifestBuilderImpl implements ManifestBuilder,
ServletContextAware {

private ServletContext servletContext;

@Override
public Manifest build(String relativePath) throws IOException {
File manifestFile = getRealPath(relativePath);
Manifest manifest = new Manifest();
manifest.read(new FileInputStream(manifestFile));
return manifest;
}

private File getRealPath(String relativePath) {

String realPath = String.format("%s%s", servletContext.getRealPath("/"), relativePath);
File manifestFile = new File(realPath);
return manifestFile;
}

@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
}

Create some sort of cache to store the manifest values in a accessible manner for actions.

public class ManifestCacheImpl implements ManifestCache,
           ServletContextAware {
 private ManifestReader reader;
 private ServletContext servletContext;
 @Override
 public String getManifestValue(String attributeName) {
 String key = String.format("MANIFEST-%s", attributeName);
 String value = (String) servletContext.getAttribute(key);
 if(value == null){
   value = reader.getManifestValue(attributeName);
   if(StringUtils.isNotEmpty(value))
     servletContext.setAttribute(key, value);
   }
 return value;
}
 @Override
public String getVersionNumber() {
 return getManifestValue("Implementation-Version");
}
 public void setManifestReader(ManifestReader reader) {
this.reader = reader;
}
 public ServletContext getServletContext() {
 return servletContext;
}
 public void setServletContext(ServletContext servletContext) {
 this.servletContext = servletContext;
}
}

Create a common Action class (or add the same logic to a action with the same responsibility) that all actions that need this dynamically renamed css inherit from. ex. GenericAction.


public class GenericAction extends ActionSupport implements ServletRequestAware,
ServletResponseAware, ServletContextAware {

private ServletContext servletContext;
protected HttpServletRequest request;
protected HttpServletResponse response;
protected HttpSession session;
protected ManifestCache manifestCache;

@Override
public void setServletContext(ServletContext servletContext) {
 this.servletContext = servletContext;
}

@Override
public void setServletRequest(HttpServletRequest httpServletRequest) {

this.request = httpServletRequest;

}

@Override
public void setServletResponse(HttpServletResponse httpServletResponse) {

this.response = httpServletResponse;

}

public HttpSession getSession(){

return request.getSession(true);

}

public ServletContext getServletContext() {

return servletContext;

}

public ManifestCache getManifestCache() {

return manifestCache;

}

public void setManifestCache(ManifestCache manifestCache) {

this.manifestCache = manifestCache;

}

public String getVersionNumber(){

return this.manifestCache.getVersionNumber();

}

public String getUrlFriendlyVersionNumber(){

return getVersionNumber().replace(".", "-");

}

}

In all jsp where you have your css link change to the following.

<link rel="stylesheet" type="text/css" href="/css/layout-<s:property value="urlFriendlyVersionNumber" default="static.css"/>">

Here we append the dynamically read property from GenericAction.getUrlFriendlyVersionNumber() to the css link path.

After this we now only need a Action which takes care of all requests made on “/css*”, disregards the version number and serves the actual “layout-static.css”.


public class VersionedCssAction extends GenericAction {

     final Logger logger = LoggerFactory.getLogger(getClass());
     @Autowired
     @Qualifier("cssResource")    private Resource resource;
     private InputStream inputStream;
     private final int CACHE_MAX_AGE = 86400;
     private String resourcePath = "/css/layout-static.css";
     @Action(value = "/css/*",
         results = {
                     @Result(
                          name = ActionSupport.SUCCESS,
                          type = "stream",
         params = {
                    "contentType", "text/css",
                    "inputName", "inputStream"
                   })
     })
public String execute() {
      response.setHeader("Cache-Control", String.format("max-age=%s", CACHE_MAX_AGE));
      inputStream = getServletContext().getResourceAsStream(resourcePath);
      return SUCCESS;
}

Thats it! As long as you create new versions for each deploy you will never get fluky behavior caused by css.

Upgrade to GWT 2.3 with Grails GWT plugin

If you during this get a bunch of [ERROR] statments in the compile log it might be that you suffered from the same memory laps that I did.

As stated in the Grails GWT plugin install instruktion you need to set the GWT_HOME environment variable. However if you are on a MAC like me there are a couple of ways to achieve this. The correct way (to make the plugin work) is that you add it in the /etc/launchd.conf file like so:


setenv GWT_HOME /mygwt/install/location

After this you need to logout/login.

SQL joined update

Today were asked to migrate a database into a new schema and from MS SQL into MySQL the solution were to de-normalise the data and export it into a CSV file. From the CSV file we imported the data into a de-normalised table from which we executed a number of insert statements to make the data adapt the new schema. One problem we faced where to reconstruct id-pairs on the joined entities. The solution were easier than we initially expected, a joined updated did the trick!


UPDATE tableA AS a
INNER JOIN tableB AS b
ON b.old_id = a.old_id
SET a.refId = b.id