Friday, December 20, 2013

Access to services from gsp views in Grails

Accessing services from views is considered bad practice, so there is no easy way to do it. It defenitely should not be overused, as it complicates testing and couples logic with presentation. However it is not necessary crime and can be handy for some cases.

For example, if you need access to user parameters. Traditional way to do it, is by using taglibs. What is less known is that you can use taglibs not just to produce text output, but also inside snippets of code in views. For example, you can use it to select users preferred language without need to inject it into every controller:

Taglib:

class UserSettingsTagLib {
    def springSecurityService

    def myLanguage = { attrs, body ->
      out << springSecurityService.currentUser?.myLanguage?.id
    }

}


Gsp:

<g:select name="language" optionKey="id" optionValue="name" value="${g.myLanguage()}" from="${Language.list().sort{it.name}}"/>


Thursday, November 21, 2013

Script to parse groovy source code

Recently, I had to parse Groovy class to extract some information. Reflection was not good as it was not easy to get all dependencies and I had to preserve comments too. This is quite easy to do by utilizing Groovydoc internals which are part of the default libraries:


import antlr.collections.AST
import org.codehaus.groovy.antlr.AntlrASTProcessor
import org.codehaus.groovy.antlr.SourceBuffer
import org.codehaus.groovy.antlr.UnicodeEscapingReader
import org.codehaus.groovy.antlr.parser.GroovyLexer
import org.codehaus.groovy.antlr.parser.GroovyRecognizer
import org.codehaus.groovy.antlr.treewalker.SourceCodeTraversal
import org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDoc
import org.codehaus.groovy.tools.groovydoc.SimpleGroovyClassDocAssembler

def reader = new File("/path/to/package/org/Groovy.groovy").newReader()
SourceBuffer sourceBuffer = new SourceBuffer()
UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(reader, sourceBuffer)
GroovyLexer lexer = new GroovyLexer(unicodeReader)
unicodeReader.setLexer(lexer)
GroovyRecognizer parser = GroovyRecognizer.make(lexer)
parser.setSourceBuffer(sourceBuffer)
parser.compilationUnit()
AST ast = parser.getAST()

def visitor = new SimpleGroovyClassDocAssembler("/path/to/package", "org/Groovy.groovy", sourceBuffer, [], new Properties(), true)
AntlrASTProcessor traverser = new SourceCodeTraversal(visitor)
traverser.process(ast)
SimpleGroovyClassDoc doc = (visitor.getGroovyClassDocs().values() as List)[0]
doc.methods().each {
  println it.name()
  println it.commentText()
  println it.annotations()
}


This is definitely not nicest Groovy code, and looks more like Java, but gets the job done. By the way, it should be possible to parse Java too, though I didn't tried to.

Friday, November 1, 2013

Traffic redirection to https in Grails behind load balancer

Grails security plugin has nice feature that allows automatically redirect queries for specific pages to https. For example, you can put this code into Config.groovy to redirect all requests:


grails.plugins.springsecurity.secureChannel.definition = [
    '/**':         'REQUIRES_SECURE_CHANNEL'
]

Unfortunately this does not work when your Tomcat is behind load balancer that does all encryption. To do it requires a little more work.

First, it is needed to specify how to detect either connection is secure or not. Standard way to do it with load balancers is to use X-Forwarded-Proto header. So it needs to be specified in Config.groovy like:

grails.plugins.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugins.springsecurity.portMapper.httpsPort = 443

Worst part, is that it requires Tomcat reconfiguration, so it is needed to update Connector element in server.xml, like:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"  proxyName="yourserver.com" proxyPort="443" secure="true" scheme="https"  />

Good part is that it works nicely locally and across multiple environments, no need for fake certificates or different builds.


Tuesday, October 8, 2013

Setting environment variables when running command via SSH in Ubuntu

There are less environment variables available when running command directly by SSH then interactively. This is because for some reason, Ubuntu does a little less for non-interactive shells and stops executing .bashrc after this line:

[ -z "$PS1" ] && return

So if you wish to run anything, it should be done before, like:

export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_21/
[ -z "$PS1" ] && return

Thursday, September 26, 2013

Convert color console output into HTML with Java

Some command line tools can print colored text, which looks nice in console itself (if it is supported), but not so nice when you need to show it in HTML:

[47;32mhello world

There is small console tool "aha" that can pipe such input and transform it directly in command line, but sometimes you have to do it from code. For such cases there is Java library Jansi which prints ANSI escape sequences into Windows consoles. Their less advertised feature is library for direct conversion between ANSI and HTML, which it does just fine:

@Grapes(
    @Grab(group='org.fusesource.jansi', module='jansi', version='1.11')
)

import org.fusesource.jansi.*

private String colorize(String text) throws IOException {
  new ByteArrayOutputStream().with {
    new HtmlAnsiOutputStream(it).with {
      write(text.getBytes("UTF-8"))
      close()
    }
    return new String(it.toByteArray(), "UTF-8");
  }
}

println colorize(" [47;32mhello world")

Thursday, September 5, 2013

Adding error messages to domain object in Grails

Sometimes it is more convenient to do some validation outside of the domain object, on the other side it is still nice to use standard error reporting facilities. For these cases, you can inject errors into domain objects like:

    if (someError) {
      domainobject.errors.rejectValue('param', "hasErrors")
    }
    ...
    if (!domainobject.hasErrors() && domainobject.save(flush: true)) {
    ...


Wednesday, August 28, 2013

Jenkins kills Tomcat or other Java process after job ends

Recently, I was adding new application deployment to Tomcat server that was started by Jenkins. Process was starting nicely, but was stopping at the end of the job. The only clue was log record:

Service exit with a return value of 143

This issue can be easily solved by adding -Xrs to JAVA_OPTS. Option description can be found at http://docs.oracle.com/javase/6/docs/technotes/tools/windows/java.html.


Thursday, August 8, 2013

Running Selenium with Groovy on PhantomJS

There is script that runs and takes snapshot of PhantomJS with Selenium:


@Grab("com.github.detro.ghostdriver:phantomjsdriver:1.0.1")

import org.openqa.selenium.*
import org.openqa.selenium.phantomjs.PhantomJSDriver
import org.openqa.selenium.remote.DesiredCapabilities

new PhantomJSDriver(new DesiredCapabilities()).with {
    manage().window().setSize(new Dimension(1028, 768))
 get("http://www.google.com")
 getScreenshotAs(OutputType.FILE).renameTo("screenshot.png")
 quit()
}



Running Selenium with Groovy on Firefox

There is small script to run and take screenshot in Firefox with Selenium from Groovy:


@Grab("org.seleniumhq.selenium:selenium-firefox-driver:2.34.0")

import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.*
 
new FirefoxDriver().with {
 get("http://www.google.com")
 getScreenshotAs(OutputType.FILE).renameTo("screenshot.png")
 quit()
}


Wednesday, July 17, 2013

Setting PATH for Jenkins slave agent

There is a lot of variables and settings available for Jenkins slave agents, but for some reason nothing worked for PATH in my case. Finally, the only configuration that did the job, was to set PATH in user's home .bashrc (.profile, profile, .bash_profile, etc. was not working) on slave node, like:

  PATH=$PATH:/opt/phantomjs-1.9.1-linux-x86_64/bin/


Thursday, June 20, 2013

Multipart file upload in Groovy HTTPBuilder

HttpClient from HttpComponents is very powerful, but super ugly library. Groovy has nice wrapper around it, called HTTPBuilder, which looks better and has DSLish API. It is just as powerful as HttpClient, as it is using it underneath. Unfortunately, it has far less documentation and bad googleability.
For example I tried to use it for file upload, and it is not in original documentation, and nothing sane on StackOverflow or likes. Fortunately, it is still possible and easy (despite HttpClient ugliness creeping in).

    def http = new HTTPBuilder( 'http://localhost:8080/' )
    http.auth.basic 'test', '123456'
    http.request( POST, JSON ) { req ->
      uri.path = '/project/addFile'
      uri.query = [ id:projectId ]
      requestContentType = 'multipart/form-data'
      MultipartEntity entity = new MultipartEntity()
      entity.addPart("file", new ByteArrayBody("123456".getBytes("UTF-8"), 'filename.jpg'))
      req.entity = entity
    }



Friday, May 24, 2013

Using JIRA API from Groovy

If you need to script some JIRA task, it is very easy to do:

@GrabResolver(name='atlassian', root='https://maven.atlassian.com/content/groups/public/')
@Grab( group ='com.atlassian.jira.plugins', module = 'jira-soapclient', version = '4.0' )

import com.atlassian.jira.rpc.soap.client.*

def jira = new JiraSoapServiceServiceLocator().getJirasoapserviceV2(new URL('http://host/rpc/soap/jirasoapservice-v2'))
String token = jira.login('user', 'pass')
println jira.getVersions(token, "PRJ").sort({ it.sequence }).find({ !it.released }).name

which takes latest unreleased version for the project PRJ.

Tuesday, April 30, 2013

Method updated() is not setting hours, minutes and seconds in Groovy Date class

Recently, I wanted to update existing date in Groovy like:


> new Date().updated(year: 2013, month: Calendar.APRIL, date: 15, hours: 0, minutes: 0, seconds: 0)
Mon Apr 15 21:59:01 EEST 2013

It sets date, month and year perfectly, but completely ignores hours, minutes and seconds.
After checking Groovy sources I found that these are incorrect property names, and correct code is:


> new Date().updated(year: 2013, month: Calendar.APRIL, date: 15, hourOfDay: 0, minute: 0, second: 0)
Mon Apr 15 00:00:00 EEST 2013

First thing is, that it is not mentioned in GroovyDoc, but what adds confusion is that Intellij IDEA autocomplets variables in this way, because Date has deprecated setters with such property names.

Wednesday, April 24, 2013

ChannelResolutionException in Spring Integration with Groovy

Recently, after launching Spring Integration beans I got weird exception:
ChannelResolutionException: no output-channel or replyChannel header available
After some googling I found out that this error means that Spring Integration tries to configure reply channel, which in my case meant that I am replying into channel-adapter, which is not possible. So basically, problem was that my service method was defined as:
def myServiceMethod()

which Spring understands as it returns something, even if it does not. So this should be told explicitly, like:
void myServiceMethod()

and this is it.

Friday, April 19, 2013

Lightweight Groovy HTTP server for testing

Recently, I was looking for really lightweight HTTP server for integration and functional testing. Minimalistic web servers looks like popular topic now and there is a bunch of them available, like Ratpack, Graffiti or Spark. But none of them looked like what I needed: really small, expressive and convenient for tests. One, that was looking best is HttpServer from JDK, but it's horrible boilerplate code is ugly even by the Java standards, so finally I decided to write one myself.

And this is the result https://github.com/dmitart/lightweightest.

It is based on JDK HttpServer, just less verbose API and tests oriented, just check examples in the README. Enjoy. But don't put it in production.

Hosting Ivy or Maven repository on Github with Gradle

If you don't have access to any public repo, but want to host libraries - then Github can be a solution.
Unfortunately, it does not provide proper interfaces for the client applications, but this is still possible.

Lets say that local root folder of your git project is /test.
First, you need to create all necessary poms and jars. To do it, you have to add this to your build.gradle file:

uploadArchives {
  repositories {
    mavenDeployer {
      repository(url: "file:///test/repo")
    }
  }
}

URL property is for proper Maven repository - for now unfortunately, Github is not, so you will have to enter some local folder. After this is added, run Gradle task uploadArchives, then commit and push all output files with git.

Unfortunately, this is not all, as SHA signature is wrong, because your git URL is not same as local. So you will need to find out proper SHA, and until you want to calculate it yourself, one easy way to do it is find some talkative Maven client, for example Grape. Luckily it is part of normal Groovy installation.

Then, you need to add new repo into Grape configuration, open ${user.home}/.groovy/grapeConfig.xml file and add your new repo like

<ibiblio name="myrepo" root="https://raw.github.com/me/mymodule/master/repo" m2compatible="true"/>

And, to get dependencies, just run Grape in verbose mode, for example like:

grape -V install my.group mymodule 0.1

It will fail, but you will get one great error message like:

...-0.1.pom: invalid sha1: expected=7f1089041d63ce7eaa5d6a35ddda3aaa606042e3 computed=8a941ef40645d449b0740023624c2f8b67b84c59 (516ms)

8a941ef40645d449b0740023624c2f8b67b84c59 is what we were looking for.
Just find file whose signature was incorrect, for example for pom it can be mymodule.pom.sha1, update it with new signature and push into git.

That is all, you have new great Maven repository with root under https://raw.github.com/me/mymodule/master/repo.


Wednesday, April 17, 2013

jQuery / Javascript method runs several times after single call

Recently, I was developing web page and attached click handler to button, which was loading some content into div element. What was unexpected, after first click - it loaded everything just fine, but each next click was increasing amount of method calls.
As I found out, problem was that after successful method execution it also loaded default page template with every new fragment, including JavaScript page initialization scripts, which was adding new handlers to all old buttons, and so on, and so on.
It was easy to fix by creating new empty template specifically for HTML fragments.
I had this problem with Grails, but any template engine with too many conventions and defaults can be vulnerable.

Wednesday, April 10, 2013

Setting style by custom property dynamically in AngularJS

Angular JS lets to set and update style and class based on some custom property. Unfortunately, it does not support placeholders now, for example:


<!-- This works -->
<td ng-style="myStyle">


<!-- This does not -->
<td ng-style="myStyle{{test}}">



Fortunately, it works with controller's methods, so this still can be done like:


<td ng-style="getMyStyle(test)">

where getMyStyle is controller's method.

Tuesday, April 2, 2013

Run background java process from Jenkins

Jenkins is using mechanism to detect spawned processes and kill them after finishing job, so if you will just start such ad-hoc background daemon process, Jenkins will kill it with warning:


Process leaked file descriptors. See http://wiki.jenkins-ci.org/display/JENKINS/Spawning+processes+from+build for more information

Fortunately, there is easy hack to tell Jenkins ignore such process, just create fake BUILD_ID and start your application, for example, this can be entered into Execute shell build step:

BUILD_ID=dontKillMe nohup java -jar test.jar &

Warning is still there, but process should be fine and running. There is more about it here.

Thursday, March 21, 2013

How to kill Tomcat server running from standalone plugin

I have demo application which is running from Grails standalone plugin and wanted to automate deployment from Jenkins. Starting such application is well documented and easy, but there is nothing about stopping it.
After quick digging plugin's code, I found that it has undocumented feature to do it. It creates server on application server port + 1, and as soon as there is connection - shuts server. So if your server port is 8080, this command from same computer will kill server:

telnet localhost 8081

Friday, February 1, 2013

ActiveMQ pool logging

If you are using org.apache.activemq.pool.PooledConnectionFactory for ActiveMQ connection pooling, it is maybe frustrating to detect server connection problems as it does not log anything at INFO level. DEBUG level contains reconnection records, but also a lot of unnecessary, boring stuff, not needed for production. Fortunately, there is logger that can be used for connections monitoring, which is not nicest, but working solution, and definitely it is better than nothing:

    debug 'org.apache.activemq.util.ThreadPoolUtils'


Friday, January 25, 2013

grails-coffeescript-resources is not working after deploying war in production

There is great Grails plugin that allows to work with CoffeeScript very easily, compiles .coffee files on the fly and does all dirty work.
However, once I tried to deploy my application to test environment, all CoffeeScript files became available in browser as is, without compilation. After some investigation I found out that problem is that it does not supports applications deployed as packed WAR files (with unpackWARs="false" in server.xml), it was pretty easy to fix by modifying plugin script grails-app/resourceMappers/CoffeeScriptResourceMapper.groovy by changing:
 
      File input = grailsApplication.parentContext.getResource(resource.sourceUrl).file

to this

      File input
      try {
        input = grailsApplication.parentContext.getResource(resource.sourceUrl).file
      } catch (FileNotFoundException e) {
        input = new File(original.absolutePath)
      }


and it should work.
One problem is that this change is inside plugin, so you can't do change in your code, and should change plugin itself. I submitted fix with pull request on GitHub, hopefully it will be merged. Until then it is possible to compile your own version from here, or just replace this one line on build server.


Friday, January 18, 2013

Working around grails.serverURL redirect in Grails 2

The most annoying issue with Grails 2 migration is that it requires redirection to grails.serverURL when it is specified. This property is needed if there are absolute links in application (in emails, for example).
First problem that I had with it, was after deploying application to test environment. We deploy production version, so all redirects became redirects to production, this could be solved by externalizing Grails configuration.
Second problem was more severe. We have following setup: load balancer with two nodes behind it. Our deployment script takes first node down, deploys, runs smoke tests, releases first node, takes second node down, deploys, smoke tests, releases.
So basically, production URL is load balancer's entry point, and when smoke tests run on node which is down it is never redirected to tested server (because it is down and it is behind load balancer), so every redirect (after spring security login, for example), breaks tests flow.
After some digging around, I found the best option is to abandon grails.serverURL - which is totally unusable now, and add to email link generation my own parameter from externalized Grails configuration (for each environment). This is sad as createLink with absolute parameter was great function and it didn't required dragging custom parameters.
That is how it is now.
What I would love to see in the future is grails.serverURL is used ONLY in all links generated with absolute:true and nowhere else, but all redirects work as if grails.serverURL not specified at all.

Thursday, January 17, 2013

"Cannot find any VM in Java Home ..." error in Tomcat

During migration from JDK 6 to 7, I found strange issue: Tomcat was working fine when starting via catalina.sh, but was failing when starting via jsvc with just this error:

Cannot find any VM in Java Home /usr/lib/jvm/jdk1.7.0_10/

Jsvc recompilation or any other measure was not helping, but finally I found out that it was running flawless with specific x64 version of JDK instead of i586 version.

Fixing GORM UserType after migration to version 2

Grails allows to define custom UserType to properties like in regular Hibernate, by specifying them next to properties in domain objects, like:


  someproperty type: MyUserType

But after migrating to Grails 2.2, these stopped working and Grails started to treat them as plain objects (enumerations in my particular case). Fortunately, this was easy to fix by defining all custom user types in Config.groovy, like:


grails.gorm.default.mapping = {
  'myproperty-type'(type: my.org.MyUserType, class: my.org.MyEnum)
}

This also defines mapping for all properties of specific type, so no need to do it in every domain class.

Wednesday, January 9, 2013

Importing plugin classes into Grails scripts

Classes from plugin src folder are not available to Grails scripts or plugin scripts itself. They can be compiled and manually loaded, but will be only available for applications or tests launched from script - not to script itself.
However it is easy to work around this issue if it is your plugin or you can rebuild it. It is only needed to compile classes into lib when packing plugin, after that all libs are loaded when running script.
For example this can be done by adding next snippet into _Events.groovy file of the plugin:


eventPackagePluginStart = {
  compile()
  ant.jar ( destfile : 'lib/pluginlibs.jar' , basedir : 'target/classes', includes:"com/myplugin/**")
}