Kohei Nozaki's blog 

Using DatabaseConfiguration of Commons Configuration


Posted on Sunday Feb 22, 2015 at 10:50PM in Technology


Commons Configuration is a very useful library which manages configurations of an application. it supported various data stores including RDBMS. I’ve done some test against RDBMS so leave this posting as a note. test was done against Commons Configuration 1.10. the project which used in test is can be obtained from my GitHub repository.

app_config Table

Assume now we have following data in a table named app_config.

Table 1. app_config Table
name value

anyJob.someProp1

abc

anyJob.someProp2

def

someJob.list

1,2,3,4,5

someJob.someProp

${anyJob.someProp1}

Create Configuration instance

First, we need to create a DatabaseConfiguration instance with following procedure:

Configuration config = new DatabaseConfiguration(dataSource, "app_config", "name", "value");

Obtain all of configuration

We can obtain all of configurations as follows:

// Obtain all of keys
for (Iterator<String> keys = config.getKeys(); keys.hasNext(); ) {
	String key = keys.next();
	Object value = config.getProperty(key);
	System.out.println(key + "=" + value);
}

It produces:

anyJob.someProp1=abc
anyJob.someProp2=gef
someJob.list=[1, 2, 3, 4, 5]
someJob.someProp=${anyJob.someProp1}

Obtain keys with particular prefix

Sometimes we’d like to filter using prefixes. this time we get keys prefixed with someJob.

// Obtain keys with particular prefix
for (Iterator<String> keys = config.getKeys("someJob"); keys.hasNext(); ) {
	String key = keys.next();
	Object value = config.getProperty(key);
	System.out.println(key + "=" + value);
}

It produces:

someJob.list=[1, 2, 3, 4, 5]
someJob.someProp=${anyJob.someProp1}

Obtain list

We can obtain comma-separated values as List as follows:

// Obtain list
System.out.println(config.getList("someJob.list")); // [1, 2, 3, 4, 5]
System.out.println(config.getString("someJob.list")); // 1

It produces:

[1, 2, 3, 4, 5]
1

Note that invocation of getString() returns only the first value.

Obtain referencing value

The value ${anyJob.someProp1} in the key someJob.someProp resolved as abc with getString() method as follows:

// Referencing a value of other key
System.out.println(config.getString("someJob.someProp")); // abc

It produces:

abc

Update

The library reflects a update of database immediately even after instantiation of DatabaseConfiguration. consider following procedure was executed after instantiation of the configuration instance.

// update value of a row
try (Connection cn = dataSource.getConnection()) {
	try (Statement st = cn.createStatement()) {
		st.executeUpdate("update app_config set value='hij' where name='anyJob.someProp1'");
	}
}

// check updated value
System.out.println(config.getString("anyJob.someProp1")); // hij
System.out.println(config.getString("someJob.someProp")); // hij

It produces:

hij
hij


Using JSL Inheritance with JBeret


Posted on Sunday Feb 22, 2015 at 06:28PM in Technology


In practical use, many boilerplate code will appear to Job definition XMLs of JSR352 batch such as definition of Listeners, Properties and attribute such as item-count of chunk element. to overcome this, there is the specification of JSL Inheritance but it deferred to next version of JBatch spec but JBeret supports this specification already. it’s very useful to eliminate annoying fragments appear repeatedly so I tested it. WildFly 8.2.0.Final was used for test.

Parent XML

Parent XML begins as follows:

<?xml version="1.0" encoding="UTF-8"?>
<job id="parent" abstract="true" version="1.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee">

    <properties>
        <property name="someJobProp" value="someJobPropValue"/>
    </properties>

    <listeners>
        <listener ref="myJobListener"/>
    </listeners>

Declared property named someJobProp become visible from child XMLs. myJobListener will be included implicitly in child XMLs as well.

Parent XML has an abstract step element which will be referenced from child XMLs as follows. these properties and listeners for a step will be included implicitly too. we can override javax.transaction.global.timeout at there. it will be affected to all of child steps.

    <step id="mySimpleStep" abstract="true">
        <properties>
            <property name="javax.transaction.global.timeout" value="1800"/>
        </properties>
        <listeners>
            <listener ref="myStepListener"/>
        </listeners>
    </step>

It is the same for chunk based step. it can be used to eliminate defining item-count for all of chunk steps.

    <step id="myChunkStep" abstract="true">
        <properties>
            <property name="javax.transaction.global.timeout" value="900"/>
            <property name="jberet.local-tx" value="true"/>
        </properties>
        <listeners>
            <listener ref="myStepListener"/>
            <listener ref="myChunkListener"/>
        </listeners>
        <chunk item-count="3"/>
    </step>

</job>

Child XML

Child XML became very simple thanks to inheritance as follows. you need to specify parent and jsl-name attributes to reference its parent. parent means the name of parent attribute. jsl-name means XML file name of referencing element.

<?xml version="1.0" encoding="UTF-8"?>
<job id="child" parent="parent" jsl-name="parent" version="1.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee">

    <step id="simpleStep" next="chunkStep" parent="mySimpleStep" jsl-name="parent">
        <batchlet ref="myBatchlet"/>
    </step>

    <step id="chunkStep" parent="myChunkStep" jsl-name="parent">
        <chunk>
            <reader ref="myItemReader"/>
            <writer ref="myItemWriter"/>
        </chunk>
    </step>

</job>

Launching example job

  1. Clone the repository

  2. Build the WAR and deploy it to your WildFly

  3. Run a JUnit test class named JobTest. it invokes the job through remote EJB invocation.

Log

You can see Properties, Listeners and item-count attribute were inherited as expected.

(Batch Thread - 1) Job child starting
(Batch Thread - 1) Job child, Step simpleStep starting
(Batch Thread - 1) hello world!
(Batch Thread - 1) jobProps: {someJobProp=someJobPropValue}
(Batch Thread - 1) stepProps: {javax.transaction.global.timeout=1800}
(Batch Thread - 1) Job child, Step simpleStep done
(Batch Thread - 1) Job child, Step chunkStep starting
(Batch Thread - 1) jobProps: {someJobProp=someJobPropValue}
(Batch Thread - 1) stepProps: {jberet.local-tx=true, javax.transaction.global.timeout=900}
(Batch Thread - 1) Job child, Step chunkStep chunk starting
(Batch Thread - 1) write: [1, 2, 3]
(Batch Thread - 1) Job child, Step chunkStep chunk done
(Batch Thread - 1) Job child, Step chunkStep chunk starting
(Batch Thread - 1) write: [4, 5, 6]
(Batch Thread - 1) Job child, Step chunkStep chunk done
(Batch Thread - 1) Job child, Step chunkStep chunk starting
(Batch Thread - 1) write: [7, 8, 9]
(Batch Thread - 1) Job child, Step chunkStep chunk done
(Batch Thread - 1) Job child, Step chunkStep chunk starting
(Batch Thread - 1) write: [0]
(Batch Thread - 1) Job child, Step chunkStep chunk done
(Batch Thread - 1) Job child, Step chunkStep done
(Batch Thread - 1) Job child done