Friday, January 31, 2014

Sending ActiveMQ messages from Groovy

Didn't found it in Google, so there is quick example how to send JMS message from Groovy script using Grab:


@Grab(group='org.apache.activemq',module = 'activemq-all', version='5.5.0')

import org.apache.activemq.ActiveMQConnectionFactory
import javax.jms.Session

new ActiveMQConnectionFactory(brokerURL: 'tcp://localhost:61616').createConnection().with {
  start()
  createSession(false, Session.AUTO_ACKNOWLEDGE).with {
    createProducer().send(createQueue("queue"), createTextMessage("test"))
  }
  close()
}


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)) {
    ...