Páginas

SyntaxHighlighter

Mostrando postagens com marcador groovy. Mostrar todas as postagens
Mostrando postagens com marcador groovy. Mostrar todas as postagens

terça-feira, 11 de outubro de 2011

Using XmlSlurper to update appengine-web.xml

I'm currently working on a project which is using GAE (Google Application Engine).
I wanted to setup Jenkins' jobs to update the different stages (acceptance, qa, uat) in our build pipeline.
To achieve that I created 3 different GAE's applications - one for each stage - and 4 Jenkins jobs: 1 template which holds the common steps and 3 others for the respective stages.
The first step of the template job updates appengine-web.xml target application and version based on parameters passed to the job.


See the groovy script below:


import groovy.xml.StreamingMarkupBuilder

//getting parameters values from environment variables
def env = System.getenv()
def workspace = env["WORKSPACE"]
def applicationName = env["TARGET_APPLICATION_NAME"]
def versionName = env["TARGET_VERSION_NAME"]
def ant = new AntBuilder()
ant.echo(message:"Opening $workspace/war/WEB-INF/appengine-web.xml")
def file = new File("$workspace/war/WEB-INF/appengine-web.xml")
def root = new XmlSlurper().parse(file)
ant.echo(message:"Updating appengine-web.xml with application: $applicationName and version: $versionName")
root.application=applicationName
root.version=versionName 
def outputBuilder = new StreamingMarkupBuilder()
String result = outputBuilder.bind{ 
   mkp.declareNamespace("":  "http://appengine.google.com/ns/1.0")    
   mkp.yield root 
}
ant.echo(message:"Writing appengine-web.xml")
file.write(result)

sexta-feira, 25 de março de 2011

Generating CSV files using sqlcmd and groovy

Just sharing a simple groovy script I wrote for generating a CSV file from the database.
It depends on SQLServer's sqlcmd command line utility.
It takes 4 input parameters - needed to open a database connection, scans the current directory for .sql files then executes each of them using sqlcmd generating a .temp file. The temp file is then processed - the first and last 2 lines are removed - and renamed to a .csv file.

def username = args[0]
def password = args[1]
def host = args[2]
def database = args[3]
def dir = './'

def ant = new AntBuilder()
def p = ~/.*\.sql/
new File( dir ).eachFileMatch(p) { f ->

    def sqlFile = f.name
    def tempCsvFile = sqlFile.replaceAll(/.sql/,'')

    def cmd = "sqlcmd -S $host -U $username -P $password -d ${database} -i ${sqlFile} -W  -o ${tempCsvFile}.temp -s ;"
    def process = cmd.execute()
    process.waitFor()

    ant.move(file: "${tempCsvFile}.temp", tofile:"${tempCsvFile}.csv", overwrite: true ) {
 filterchain(){
  headfilter(lines:"-1", skip: "2")
  tailfilter(lines: "-1", skip: "2" )
  ignoreblank()
 }
    }
}

This could probably be achieved in many other ways.
But it worked like a charm for me!!

sexta-feira, 29 de outubro de 2010

Using Text instead of String to store large texts in GAE's datastore

I just started playing with Gaelyk and GAE. The goal is to learn the GAE APIs and services and improve my groovy foo!
So, in order to practice it I've chosen to develop a simple pastebin like application using Gaelyk.

I started it by modeling the main entity: Snippet, which is a very simple POGO with only 3 properties:

class Snippet implements Serializable {
 
 String name
 String text
 String language
 
}

The groovylet below ilustrates how we can easily instantiate a new entity from the posted request parameters and then persist it into the data store.

def snippet = new Snippet(params);

// coerce a POJO into an entity
def snippetEntity = snippet as Entity
snippetEntity.save()

forward "/snippet.gptl"

So far so good. After some tests I got the following error:

Error: GroovyServlet Error: script: '/WEB-INF/groovy/snippet/create.groovy': Script processing failed.name: String properties must be 500 characters or less. Instead, use com.google.appengine.api.datastore.Text, which can store strings of any length.com.google.appengine.api.datastore.DataTypeUtils.checkSupportedSingleValue(DataTypeUtils.java:192)

The message is very self explanatory. I changed the Snippet and the groovylet respectively to:

import com.google.appengine.api.datastore.Text

class Snippet implements Serializable {
 
 String name
 Text text
 String language
 
}

// create.groovy
def snippet = new Snippet();
snippet.name = params.name;
snippet.language = params.language;
snippet.text = params.text as Text;

def snippetEntity = snippet as Entity
snippetEntity.save()


Note that I changed property type from String to Text and had to set each property separately in the groovylet because there is no autocasting support for Text types.

You can check the last deployed version in AppEngine here: Snippetr
And the source code here: http://code.google.com/p/snippetr/

quinta-feira, 2 de julho de 2009

Grails Xmpp Plugin 0.1 Released

I just finished and released the first official version of the Grails Xmpp Plugin. Its documentation is still a working in progress but enough to get started.
There are still some known issues and new ideas of improvements but I couldn't wait to release it. :-)
Hopefully people will start using it and then I 'll have some feedbacks!

Enjoy

domingo, 31 de maio de 2009

Grails XMPP (jabber) Plugin

I´ve been playing with Grails for over a year. Recently I started reading and studying about XMPP and its possible applications and how it is being used out there.

So I came up with an idea to put together both techologies: Grails/Groovy and XMPP.
The main idea is to create a grails plugin that eases the development of real-time xmpp based web applications.

The plugin can be built upon the Smack API and would provide XMPP/IM based services to grails applications.

Below the list of functionalities I´d like the plugin to provide divided in two distinct approaches:

Approach 1: One Roster per application

  • Provide the grails application with a Roster
  • The Roster (might) automatically connect to a xmpp server and broadcast its presence on application startup - Bootstrap (XmppBootstrap) or InitializingBean??
  • Roster configuration ( jid, pwd, server host and port, etc ) should go to?? Config.goovy
  • Provide a XmppController with Roster functionalities
  • Provide a XmppServices with Roster functionalities (sending messages, changing roster status, sending presence packets, accepting and sending invitations, etc)
  • Auto detection and registering of xmpp message listeners
  • Repass grails proxy configuration to xmpp connection settings
  • org.jivesoftware.smack.proxy.ProxyInfo
    org.jivesoftware.smack.ConnectionConfiguration
  • Ability to expose Service´s methods as IM commands (something similar to what friendfeed is doing). The method name would map to the IM command and would be automatically invoked when incoming messages starting with "@" arrived
Approach 2 - Multiple Rosters per application

Another approach would be having multiple Rosters (I´m calling them xmpp bots) including the functionalities above mentioned and:

  • New script to create xmpp bots - i.e. grails create-xmpp-bot;
  • Bots would be configured via static properties: jidId, pwd, host, etc
  • The plugin would auto-detect these bots (grails-app/xmpp-bots/*XmppBot.groovy), create the respective spring beans, register them as message listeners, initialize them at application startup, etc

I´ll probably go with the first approach as it makes more sense to me. It´s difficult to imagine needing to have more than one agent per application.
Another aspect that should be taken into consideration is how the subscription will be handled.
I´ve already started the coding but I still have lots of design decisions to make and lots of work too - haven´t got enough time to dedicate to this parallel project lately.