Database migration with Flyway

Flyway in an extremely convenient database migraton tool.
First and foremost it integrates wonderfully with maven.
But one of its biggest assets is the ability to run both sql migration scripts and java migration scripts.

Let us start with a simple maven project

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>migration</groupId>
    <artifactId>com.gkatzioura</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <flyway.version>3.1</flyway.version>
        <mysql.driver.version>5.1.33</mysql.driver.version>
        <database.url>{your jdbc url}</database.url>
        <database.user>{your database user}</database.user>
        <databese.password>{your database password}</databese.password>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
            <version>${flyway.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
                <version>${flyway.version}</version>
                <configuration>
                    <baselineOnMigrate>true</baselineOnMigrate>
                    <url>${database.url}</url>
                    <user>${database.user}</user>
                    <password>${databese.password}</password>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>${mysql.driver.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

When you issue through maven

mvn flyway:migrate

Then flyway will will lookup on the db/migration folder of your target to find any migration files. This folder can be changed by altering the content of the locations inside the configuration of the flyway plugin.

For my first migration file I will use sql

The sql file will be located on the db/migration folder which will reside on the maven resources folder.
The name would be V1_1__Create_Persons.sql
Therefore the full path would be src/main/resources/db/migration/V1_1__Create_Persons.sql

CREATE TABLE Persons
(
PersonID bigint(20) NOT NULL AUTO_INCREMENT,
LastName varchar(255),
FirstName varchar(255),
); 

The second file would be a java file.
It will be located on the package db.migration folder which will reside on the maven src folder.
The name would be V1_2__Insert_Persons.java
Therefore the full path would be src/main/java/db/migration/V1_2__Insert_Persons.java

package db.migration;

import org.flywaydb.core.api.migration.jdbc.JdbcMigration;

import java.sql.Connection;
import java.sql.Statement;

public class V1_2__Insert_Persons implements JdbcMigration
{

	@Override
	public void migrate(Connection connection) throws Exception
	{
		Statement stmt = connection.createStatement();

		stmt.addBatch("INSERT INTO Persons (FirstName,LastName) VALUES ('Emmanouil','Gkatziouras')");

		stmt.addBatch("INSERT INTO Persons (FirstName,LastName) VALUES ('Do not know','this guy')");

		try {
			stmt.executeBatch();
		}
		finally {
			stmt.close();
		}

	}

}

Since we provide a java file it is wise to call flyway by

mvn clean compile flyway:migrate
Advertisement

Aspect Oriented Programming: Qi4j

Qi4j is an emerging framework for composition, injection and aspect oriented programming.

Its main asset is composition however it provides us with tools such as concerns and sideofs in order to apply aspect oriented programming.

I will use the same example with the employees as I did on the previous posts by using Spring and Java EE.
Each employee whether he is a supervisor or a worker will have a different behavior before entering the working area.

First let us start with the interface

 
package com.gkatzioura;

public interface Employee {

    public void enterWorkArea();

}

Also I will create the default implementation for the Employee interface

 
package com.gkatzioura;

import java.util.logging.Logger;

public class EmployeeMixin implements Employee {

    private static final Logger LOGGER = Logger.getLogger(EmployeeMixin.class.getName());

    @Override
    public void enterWorkArea() {

        LOGGER.info("I will enter the work area");

    }

}

Now I will create two transient composites a worker and an employee.

 
package com.gkatzioura;

import org.qi4j.api.composite.TransientComposite;

public interface Worker extends Employee,TransientComposite {
}

 
package com.gkatzioura;

import org.qi4j.api.composite.TransientComposite;

public interface Supervisor extends Employee,TransientComposite {
}

And for each composite I will create a concern. Concern is the equivalent for MethodBeforeAdvice on spring.

 
package com.gkatzioura;

import org.qi4j.api.concern.ConcernOf;
import java.util.logging.Logger;

public class WorkerBeforeConcern extends ConcernOf<Employee> implements Employee{

    private static final Logger LOGGER = Logger.getLogger(WorkerBeforeConcern.class.getName());

    @Override
    public void enterWorkArea() {

        LOGGER.info("Informing the supervisor that I have arrived");

        next.enterWorkArea();
    }
}
 
package com.gkatzioura;

import org.qi4j.api.concern.ConcernOf;
import java.util.logging.Logger;

public class SupervisorBeforeConcern extends ConcernOf<Employee> implements Employee {

    private static final Logger LOGGER = Logger.getLogger(SupervisorBeforeConcern.class.getName());

    @Override
    public void enterWorkArea() {

        LOGGER.info("Check if everything is ok");

        next.enterWorkArea();
    }
}

The last class that remains is to assemble our environment.

 
package com.gkatzioura;

import org.qi4j.api.activation.ActivationException;
import org.qi4j.api.structure.Application;
import org.qi4j.api.structure.Module;
import org.qi4j.bootstrap.*;
import java.util.logging.Logger;

public class Main {

    private static Energy4Java qi4j;
    private static Application application;

    private static final Logger LOGGER = Logger.getLogger(Main.class.getName());

    public static void main(String[] args) throws AssemblyException, ActivationException {

        qi4j = new Energy4Java();
        Application application = qi4j.newApplication(new ApplicationAssembler() {

            @Override
            public ApplicationAssembly assemble(ApplicationAssemblyFactory factory)
                    throws AssemblyException {

                ApplicationAssembly assembly = factory.newApplicationAssembly();

                LayerAssembly rootLayer = assembly.layer("layer");
                ModuleAssembly rootModule = rootLayer.module("module");

                rootModule.transients(Supervisor.class)
                        .withMixins(EmployeeMixin.class)
                        .withConcerns(SupervisorBeforeConcern.class);
                rootModule.transients(Worker.class)
                        .withMixins(EmployeeMixin.class).
                        withConcerns(WorkerBeforeConcern.class);

                return assembly;
            }
        });

        application.activate();

        Module module = application.findModule("layer", "module");

        Employee supervisor = module.newTransient(Supervisor.class);
        Worker worker = module.newTransient(Worker.class);

        supervisor.enterWorkArea();

        worker.enterWorkArea();

    }    
}

Liang’s hyphenation algorithm implementation in node.js

Currently I am involved in a project that requires some string hyphenation. Initially I took a shot by using Liang’s hyphenation algorithm (taken from here liang hyphenation in python).
However it could not match my needs therefore I had to switch to the one open-office uses.

Anyway here it is the javascript implementation as a node.js module.


function LiangHyphenator(patterns) {

    this.tree = {}
    this.patterns = patterns

    for(var i= 0;i<patterns.length;i++) {
        var pattern = patterns[i]

        this.__insertPattern(pattern)
    }

}

LiangHyphenator.prototype.__insertPattern = function(pattern) {

    var chars = this.__clearPattern(pattern)
    var points = this.__createPoints(pattern)

    this.__addPatternToTree(points,chars)
}

LiangHyphenator.prototype.__clearPattern = function(pattern) {
    var numericsExpression = new RegExp('[0-9]','g')
    return pattern.replace(numericsExpression,'')
}

LiangHyphenator.prototype.__createPoints = function(pattern) {

    var charExpression = new RegExp('[.a-z]','g')
    var splitted = pattern.split(charExpression)

    for(var i= 0;i<splitted.length;i++) {
        if(splitted[i]==='') {
            splitted[i]=0
        } else {
            splitted[i] = parseInt(splitted[i])
        }
    }

    return splitted
}

LiangHyphenator.prototype.__addPatternToTree = function(points,chars) {
    var tree = this.tree
    for(var i=0;i<chars.length;i++) {

        var c = chars[i]
        if(!tree[c]) {
            tree[c] = {}
        }
        tree = tree[c]

    }


    tree['None'] = points
}

LiangHyphenator.prototype.hyphenateWord = function(word) {
    if(word.length<=4) {
        return [word]
    }

    var work = '.'+word.toLowerCase()+'.'

    var points = this.__createZeroArray(work.length+1)

    var tree = {}

    for(var j=0;j<work.length;j++) {

        var restWord = work.slice(j)
        tree = this.tree

        for(var i=0;i<restWord.length;i++) {
            var char = restWord[i]
            if(tree[char]) {
                tree = tree[char]
                if(tree['None']) {
                    var p = tree['None']
                    for(var pi=0;pi< p.length;pi++) {
                        points[pi+j] = Math.max(points[pi+j],p[pi])
                    }
                }
            } else {
                break
            }
        }
    }

    points[1] = 0
    points[2] = 0
    points[points.length-2] = 0
    points[points.length-3] = 0

    var pieces = ['']
    var zipped = this.__zip([word.split(''),points.slice(2)])

    for(var i=0;i<zipped.length;i++) {
        var c = zipped[i][0]
        var p = zipped[i][1]

        pieces[pieces.length-1] += c

        if(p%2!=0) {
            pieces.push('')
        }
    }

    return pieces

}

LiangHyphenator.prototype.__createZeroArray = function(size) {

    zeroArray = []

    for(var i=0;i<size;i++) {
        zeroArray.push(0)
    }

    return zeroArray
}

LiangHyphenator.prototype.__zip = function (arrays) {
    var serial = Array.apply(null,Array(arrays[0].length)).map(function(_,i){
        return arrays.map(function(array){return array[i]})
    });

    return serial
}


module.exports = LiangHyphenator

Aspect Oriented Programming: Java EE

CDI is a part of the Java EE farmework which provides us with AOP.

This example is the same one with the spirng aop example post. I will display the behaviour of two beans with the same definition but each one has a different aspect, more specific they will use a different interceptor.

The Entered annotation would be our interceptor binding

package com.gkatzioura;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;

@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface Entered {
    
}

The employee interface will be used to create the beans for this project.

package com.gkatzioura;

import javax.ejb.Local;
import javax.ejb.Singleton;

@Local
public interface Employee {
    
    @Entered
    public void enterWorkArea();
    
}

We will have two different kind of advices.
The SupervisorBeforeAdvice

package com.gkatzioura;

import java.io.Serializable;
import java.util.logging.Logger;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

@Entered
@Interceptor
public class SupervisorBeforeAdvice implements Serializable{
    
    private static final Logger LOGGER = Logger.getLogger(SupervisorBeforeAdvice.class.toString());
    
    @AroundInvoke
    protected Object protocolInvocation(final InvocationContext invocationContext) throws Exception {

        if(invocationContext.getMethod().getName().equals("enterWorkArea")) {
            LOGGER.info("Check if everything is ok");
        }
        
        return invocationContext.proceed();
    }
    
}

And the WorkerBeforeAdvice

package com.gkatzioura;

import java.io.Serializable;
import java.util.logging.Logger;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

@Entered
@Interceptor
public class WorkerBeforeAdvice implements Serializable {
    
    private static final Logger LOGGER = Logger.getLogger(WorkerBeforeAdvice.class.toString());
    
    @AroundInvoke
    protected Object protocolInvocation(final InvocationContext invocationContext) throws Exception {
        
        if(invocationContext.getMethod().getName().equals("enterWorkArea")) {
            LOGGER.info("Informing the supervisor that I have arrived");
        }
        
        return invocationContext.proceed();
    }
    
}

Two different beans will implement our employee interface.

Supervisor

package com.gkatzioura;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless
public class SupervisorEmployee implements Employee{

    @Override
    @Interceptors(SupervisorBeforeAdvice.class)
    public void enterWorkArea() {
    
    }
    
}

And worker

package com.gkatzioura;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless
public class WorkerEmployee implements Employee{

    @Override
    @Interceptors(WorkerBeforeAdvice.class)
    public void enterWorkArea() {
    }
    
}

I will use JAX-RS to cal those beans

Application configuration

package com.gkatzioura.jersey;

import javax.ws.rs.core.Application;

@javax.ws.rs.ApplicationPath("rest")
public class ApplicationConfig extends Application {

}

And calling the two beans from different endpoints

package com.gkatzioura.jersey;


import com.gkatzioura.Employee;
import com.gkatzioura.SupervisorBeforeAdvice;
import com.gkatzioura.WorkerBeforeAdvice;
import javax.ejb.EJB;
import javax.interceptor.Interceptors;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/")
public class AspectEndpoint {
    
    @EJB(beanName = "WorkerEmployee")
    Employee worker;
    
    @EJB(beanName = "SupervisorEmployee")
    Employee supervisor;
    
    @GET
    @Path("/worker/enter")
    public String workerEnter() {
        worker.enterWorkArea();
        return "worker entered";
    }
    
    @GET
    @Path("/supervisor/enter")
    public String supervisorEnter() {
        supervisor.enterWorkArea();
        return "supervisor entered";
    }
    
}

Connecting to JMX through Jython

Jython is great when you want a dynamically typed language based on the JVM.

Also comes really in handy when you want to write small monitoring scripts based on JMX.This is an examble on how to call a function from a MBean through Jython using JMX.

jmxaction.py

from javax.management.remote import JMXConnector
from javax.management.remote import JMXConnectorFactory
from javax.management.remote import JMXServiceURL
from javax.management import MBeanServerConnection
from javax.management import MBeanInfo
from javax.management import ObjectName
from java.lang import String

from jarray import array
import sys   

if __name__=='__main__':
        
        if len(sys.argv)> 5:
                serverUrl = sys.argv[1]
                username = sys.argv[2]
                password = sys.argv[3] 
                beanName = sys.argv[4]
                action = sys.argv[5]
        else:
                sys.exit(-1)
        credentials = array([username,password],String)
        environment = {JMXConnector.CREDENTIALS:credentials}

        jmxServiceUrl = JMXServiceURL('service:jmx:rmi:///jndi/rmi://'+serverUrl+':9999/jmxrmi');
        jmxConnector = JMXConnectorFactory.connect(jmxServiceUrl,environment);
        mBeanServerConnection = jmxConnector.getMBeanServerConnection()
        objectName = ObjectName(beanName);
        mBeanServerConnection.invoke(objectName,action,None,None)
        jmxConnector.close()

By calling the script

jython jmxaction.py {ip} {jmx user} {jmx password} {mbean name} {action}

You can invoke the action of the mbean specified.

Participating in the Summer AppCamp

This is the first post of this blog .And this one is about great news,really great news.

Me , Akasoglou Kostantinos and  Tsamouridis Vladimiros are going to participate in the Summer AppCamp .So what is the Summer AppCamp about ? It is a program focusing on the developement of mobile applications but you are not on your own on this one. Yes you guessed right we have mentors and we have APP CAMPUSES !!!!.

It is really great to get chosen for the AppCamp among other teams ,so we hope everything is going to be fine and making some really great applications.

Akasoglou Konstantinos blog
AppCamp