Tuesday, December 21, 2010

registering jboss to start by default and comforms to chkconfig

currently I had yet another binbase install and it turned out that my standard jboss script is not chkconfig compatible.

So it was time todo a rewrite


#! /bin/bash
#
# network Bring up/down jboss
#
# chkconfig: 345 20 80
# description: Starts and stops the jboss server
#
# /etc/rc.d/init.d/jboss
# See how we were called.

#define where jboss is - this is the directory containing directories log, bin, conf etc
JBOSS_HOME=/share/apps/jboss

#define the user under which jboss will run, or use 'RUNASIS' to run as the current user
JBOSS_USER=${JBOSS_USER:-"root"}

#make sure java is in your path
JAVAPTH=/usr/java/latest/bin/java

#configuration to use, usually one of 'minimal', 'default', 'all'
JBOSS_CONF=${JBOSS_CONF:-"all"}
JBOSS_HOST=0.0.0.0

JBOSS_CONSOLE=$JBOSS_HOME/console.log
#if JBOSS_HOST specified, use -b to bind jboss services to that address
JBOSS_BIND_ADDR=${JBOSS_HOST:+"-b $JBOSS_HOST"}

#define the classpath for the shutdown class
JBOSSCP=${JBOSSCP:-"$JBOSS_HOME/bin/shutdown.jar:$JBOSS_HOME/client/jnet.jar"}

#define the script to use to start jboss
JBOSSSH=${JBOSSSH:-"$JBOSS_HOME/bin/run.sh -c $JBOSS_CONF $JBOSS_BIND_ADDR"}

if [ "$JBOSS_USER" = "RUNASIS" ]; then
SUBIT=""
else
SUBIT="su - $JBOSS_USER -c "
fi

if [ -n "$JBOSS_CONSOLE" -a ! -d "$JBOSS_CONSOLE" ]; then
# ensure the file exists
touch $JBOSS_CONSOLE
if [ ! -z "$SUBIT" ]; then
chown $JBOSS_USER $JBOSS_CONSOLE
fi
fi

Saturday, December 18, 2010

grails - providing your own plugins configuration

sometimes you want to share some services in a plugin, which needs to be configured at runtime.

The easiest way is to provide a simple file in the grails conf diretory of your plugin and just read it and access it at runtime.

How to?

our little helper:


package binbase.core

import grails.util.GrailsUtil
import org.codehaus.groovy.grails.commons.GrailsApplication

/**
* Created by IntelliJ IDEA.
* User: wohlgemuth
* Date: 12/18/10
* Time: 1:00 AM
* To change this template use File | Settings | File Templates.
*/
class BinBaseConfigReader {

private static ConfigObject config = initialize()

/**
* initializes the object
* @return
*/
static ConfigObject initialize() {
return new ConfigSlurper().parse(new GroovyClassLoader(BinBaseConfigReader.class.getClassLoader()).loadClass('BinBaseConfig'))
}

/**
* returns the server
* @return
*/
static String getServer() {
if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_TEST)) {
return config.binbase.test.server.toString()
}
else if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_DEVELOPMENT)) {
return config.binbase.development.server.toString()
}
else if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_PRODUCTION)) {
return config.binbase.production.server.toString()

}
else {
throw new RuntimeException("unexspected enviroment found")
}
}
}



our configuration


/**
* this file contains the binbase configuration for this plugin.
*
*/
binbase {
production {
key = "dasdasd"
server = "10.1.1.1"
}
test {
key = "dasdasd"
server = "10.2.2.2"
}
development {
key = "dasdasd"
server = "127.0.0.1"
}
}


and to access it in your, say spring configuration?


jndiBinBaseTemplate(org.springframework.jndi.JndiTemplate) {

environment = [
"java.naming.factory.initial": "org.jnp.interfaces.NamingContextFactory",
"java.naming.factory.url.pkgs": "org.jboss.naming:org.jnp.interfaces",
"java.naming.provider.url": "${BinBaseConfigReader.getServer()}:1099".toString()
]
}


easy, isn't it?

grails - testing service, which accesses ejb's

this night I just wanted to write a quick grails plugin to access my BinBase database system.

Since I'm a smart developer I start with a simple spring dsl file and write a test.



// Place your Spring DSL code here
beans = {

jndiBinBaseTemplate(org.springframework.jndi.JndiTemplate) {

environment = [
"java.naming.factory.initial": "org.jnp.interfaces.NamingContextFactory",
"java.naming.factory.url.pkgs": "org.jboss.naming:org.jnp.interfaces",
"java.naming.provider.url": "localhost:1099"
]
}

/**
* connection to the cluster configuration
*/
clusterConfigService(SimpleRemoteStatelessSessionProxyFactoryBean) { bean ->
businessInterface = "edu.ucdavis.genomics.metabolomics.binbase.cluster.ejb.delegate.ClusterConfigService"
jndiName = "clusterservice/ClusterConfigServiceBean/remote"
jndiTemplate = ref(jndiBinBaseTemplate)
}

}


and the test code is simple enough



class BinBaseSchedulingServiceTests extends GroovyTestCase {


ClusterConfigService clusterConfigService

protected void setUp() {
super.setUp()
}

protected void tearDown() {
super.tearDown()
}

public void testTest(){
assertTrue(clusterConfigService.username != null)
}
}


the variable 'ClusterConfigService' is an stateless session bean in a jboss container and I know it works...

except grails is complaining:



org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clusterConfigService': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1412)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory.doCreateBean(ReloadAwareAutowireCapableBeanFactory.java:135)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at
....lots and lots of more...
Caused by: javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
at org.springframework.mock.jndi.SimpleNamingContext.lookup(SimpleNamingContext.java:132)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105)
at org.springframework.ejb.access.AbstractRemoteSlsbInvokerInterceptor.lookup(AbstractRemoteSlsbInvokerInterceptor.java:100)
at org.springframework.ejb.access.AbstractSlsbInvokerInterceptor.refreshHome(AbstractSlsbInvokerInterceptor.java:122)
at
...lots and lots of more...
[23:59:35,938] [ERROR] [main] [StackTrace] [Sanitizing stacktrace:]
javax.naming.NameNotFoundException: Name [clusterservice/ClusterConfigServiceBean/remote] not bound; 0 bindings: []
at org.springframework.mock.jndi.SimpleNamingContext.lookup(SimpleNamingContext.java:132)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)




mhm doesn't make much sense. Reason for the failure is that grails decides to mock the access, which is normally ok. But in our case really really not desired.

After all we want to access the application server context!

But it keeps jumping to the 'org.springframework.mock.jndi.SimpleNamingContext' mocking context.

So the only solution is this slightly dirty hack...


/***
* we do not need mocking in this plugin...
*/
if (org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder) {
org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder.deactivate()
}



and promptly it passes.

Since we only want to change this for test cases, we add yet another conditon and our resources.groovy file ends up looking like


import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean
import grails.util.GrailsUtil
import org.codehaus.groovy.grails.commons.GrailsApplication

/** *
* we do not need mocking in this plugin...
*/
if (GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_TEST)) {
println "warning disabling mocking context!!! to make remote ejb's work"
if (org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder) {
org.springframework.mock.jndi.SimpleNamingContextBuilder.currentContextBuilder.deactivate()
}
}

// Place your Spring DSL code here
beans = {

jndiBinBaseTemplate(org.springframework.jndi.JndiTemplate) {

environment = [
"java.naming.factory.initial": "org.jnp.interfaces.NamingContextFactory",
"java.naming.factory.url.pkgs": "org.jboss.naming:org.jnp.interfaces",
"java.naming.provider.url": "eros.fiehnlab.ucdavis.edu:1099"
]
}

/**
* connection to the cluster configuration
*/
clusterConfigService(SimpleRemoteStatelessSessionProxyFactoryBean) { bean ->
businessInterface = "edu.ucdavis.genomics.metabolomics.binbase.cluster.ejb.delegate.ClusterConfigService"
jndiName = "clusterservice/ClusterConfigServiceBean/remote"
jndiTemplate = ref(jndiBinBaseTemplate)
}

}

Thursday, December 16, 2010

Grails 1.3.5 webtests - custom steps to reset the database

once in a while I have the trouble that I want to reset the complete database during webtests or to make a snapshot of the current database while running the test.

So we use the great dbunit plugin to dump the database in one step:


import javax.sql.DataSource
import grails.plugin.remotecontrol.RemoteControl
import org.dbunit.database.DatabaseConnection
import org.dbunit.dataset.IDataSet
import org.dbunit.database.IDatabaseConnection
import org.dbunit.dataset.xml.FlatXmlDataSet
/**
* Created by IntelliJ IDEA.
* User: wohlgemuth
* Date: Nov 24, 2010
* Time: 3:46:47 PM
* To change this template use File | Settings | File Templates.
*/
class DumpDatabaseStep extends com.canoo.webtest.steps.Step {

String fileName = "result.xml"
/**
* resets the database
*/
void doExecute() {

RemoteControl remote = new RemoteControl()
try {

def outputFile = fileName
remote {
File file = new File("target/test-reports/data")
file.mkdirs()

DataSource dataSource = ctx.dataSource

IDatabaseConnection connection = new DatabaseConnection(dataSource.connection)

IDataSet fullDataSet = connection.createDataSet()

File out = new File(file, outputFile)

int counter = 1;

boolean run = out.exists()
while (run) {
out = new File(file, "${counter}-${outputFile}")

run = out.exists()
if (counter == 100) {
println "killed after 100 runs.."
run = false
}
counter++
}

FlatXmlDataSet.write(fullDataSet, new FileOutputStream(out))

null
}
}
catch (Exception e) {
e.printStackTrace()

throw e
}

}
}


and also to reset the complete database in another step


import grails.plugin.remotecontrol.RemoteControl
import javax.sql.DataSource
import groovy.sql.Sql

/**
* simple step which resets the complete database
*/
class ResetDatabaseStep extends com.canoo.webtest.steps.Step {

/**
* resets the database
*/
void doExecute() {

try {
DbUnitOperator.create()


RemoteControl remote = new RemoteControl()

remote.exec {
try {
DataSource dataSource = ctx.dataSource
Sql sql = Sql.newInstance(dataSource)

sql.execute("DROP SEQUENCE MINIX_ID")
sql.execute("CREATE SEQUENCE MINIX_ID START WITH 1000 INCREMENT BY 1")
}
catch (Exception e) {
e.printStackTrace()
throw e
}
}


}
catch (Exception e) {
println "error: ${e.getMessage()}"
e.printStackTrace()
throw new RuntimeException(e)
}

}
}

Grails 1.3.5 webtests and JQuery trouble

recently I migrated my prototype code over to JQuery and promptly all my webtest's failed with a lot of error messages and exceptions.

Like:


"TypeError: Cannot find function createComment in
object [object]. (FunctionalTestCase.groovy#372)"


So during some googeling I found these reports:

old htmlunit version

replacing version

Which led to me reporting:

my approach

and the final solution was to put this into your 'BuildConfig.groovy'


plugin("webtest") {
test('net.sourceforge.htmlunit:htmlunit:2.8-SNAPSHOT') {
excludes 'xalan'
excludes 'xml-apis'
}
test('com.canoo.webtest:webtest:3.1-SNAPSHOT') {
excludes 'xalan'
excludes 'xml-apis'
}
test('xalan:xalan:2.7.0') {
excludes 'xml-apis'
}
}