21 Haziran 2012 Perşembe

Reloadable message bundles with Spring's ReloadableResourceBundleMessageSource

Spring has a very nice class which saves our lives for reloading .properties files which we use in our applications often.

Say we have a bundle named bundle.properties in our application's classpath and there is a property named sample.property:

sample.property = Matrix Reloaded

We will define a ReloadableResourceBundleMessageSource in our application context for this bundle:


        
        


basename property is the bundle file name and the cacheSeconds property is the duration in seconds which the properties are cached. In the example above 60 seconds is the cache duration, after 60 seconds the message source will be refreshed.

Then in our application we can get a property as:

String sampleProperty = messageSource.getMessage("sample.property", null, null);

Our property can also be parametric. The second null parameter in the function above is the object array for parameters defined. In our sample.property we do not have any parameters so the second parameter is null. And the third parameter is the Locale which the property will be read.


20 Nisan 2012 Cuma

Intercepting a Spring bean method with Spring AOP

Spring can give us an ability to intercept a Spring Bean method easily. We can do some job before or after method proceeding. And also get the method return result and process it after the invokation.
Firstly we determine the method of a bean which will be intercepted. For example a Spring bean:

Let's say it has a sample method named sampleMethod. We should create a method interceptor which implements org.aopalliance.intercept.MethodInterceptor:
public class SampleInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
         methodInvocation.proceed();
    } 
}
And then let's define it as a bean:

Then a point cut for the sample method which extends org.springframework.aop.support.DynamicMethodMatcherPointcut:
public class SampleMethodPointCut extends DynamicMethodMatcherPointcut {
    private Class clazz;
    private String methodName;

    public SampleMethodPointCut (Class clazz, String methodName) {
        this.clazz = clazz;
        this.methodName = methodName;
    }

    public boolean matches(Method method, Class cls) {
        return (methodName.equals(method.getName()));
    }

    public boolean matches(Method method, Class cls, Object[] args) {
        return true;
    }

    public ClassFilter getClassFilter() {
        return new ClassFilter() {
            public boolean matches(Class cls) {
                return (cls == clazz);
            }
        };
    }
}

      
      

And then we should define our point cut advisor:

       
       

Finally we should define bean name auto proxy creator:
    
        
        
            
                sampleBean
            
        
        
            
                sendMethodSplitterAdvisor
            
        
    
Our sampleMethod of sampleBean will be cut by our sample interceptor :)

21 Mart 2012 Çarşamba

Generating jax-ws classes of an endpoint with wsgen

An example jax-ws end point class:

package com.sample;

@WebService(serviceName = "sampleEndPoint")
public class SampleEndPoint {
    @WebMethod
    public boolean sampleWebMethod(@WebParam(name = "parameter") int parameter){
        return true;
    }
}
After the compilation of this class, we may want to generate request and response classes of this service. wsgen command is used for this purpose:
wsgen -keep -verbose -cp . com.sample.SampleEndPoint 

After the generation is done, we have two Java classes. One is for request and the other is for the response.
Request class is:
@XmlRootElement(name = "sampleWebMethod", namespace = "http://sample.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "sampleWebMethod", namespace = "http://sample.com/")
public class Trigger {

    @XmlElement(name = "parameter", namespace = "")
    private int parameter;

    public int getParameter() {
        return this.parameter;
    }

    public void setParameter(int parameter) {
        this.parameter= parameter;
    }
}
and the response class is:
@XmlRootElement(name = "sampleWebMethodResponse", namespace = "http://sample.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "sampleWebMethodResponse", namespace = "http://sample.com/")
public class SampleWebMethodResponse {

    @XmlElement(name = "return", namespace = "")
    private boolean _return;

    public boolean isReturn() {
        return this._return;
    }

    public void setReturn(boolean _return) {
        this._return = _return;
    }

}

Spring JdbcTemplate get inserted id

Getting the primary key after insertion is done with Spring JdbcTemplate:

        
KeyHolder keyHolder = new GeneratedKeyHolder();
getJdbcTemplate().update(new PreparedStatementCreator() {
     public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
          PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"id of the corresponding table"});
          return ps;
     }
}, keyHolder);
int insertedId = keyHolder.getKey().intValue();
where insertSql is the query for insertion. The name of the id field is given while preparing the statement. Then after the insertion, the inserted id can be taken GeneratedKeyHolder's key value.

20 Ekim 2011 Perşembe

SSH client connection example with JCraft's Java Secure Channel (JSch)

One of the best libraries for SSH connection through Java is JSch. It is JCraft's utility.

Maven dependency for the latest version of Jsch is:

   com.jcraft
   jsch
   0.1.44-1


The main block of the code below is for connecting to the server through SSH, running "ls -la" command and printing the response to System.out

import com.jcraft.jsch.*;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class SSHClient {
    public static void main(String[] args) throws JSchException, IOException {
        String endLineStr = " # "; // it is dependant to the server
        String host = ""; // host IP
        String user = ""; // username for SSH connection
        String password = ""; // password for SSH connection
        int port = 22; // default SSH port

        JSch shell = new JSch();
        // get a new session  
        Session session = shell.getSession(user, host, port);

        // set user password and connect to a channel
        session.setUserInfo(new SSHUserInfo(password));
        session.connect();
        Channel channel = session.openChannel("shell");
        channel.connect();

        DataInputStream dataIn = new DataInputStream(channel.getInputStream());
        DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());

        // send ls command to the server
        dataOut.writeBytes("ls -la\r\n");
        dataOut.flush();

        // and print the response 
        String line = dataIn.readLine();
        System.out.println(line);
        while(!line.endsWith(endLineStr)) {
            System.out.println(line);
            line = dataIn.readLine();
        }
        dataIn.close();
        dataOut.close();
        channel.disconnect();
        session.disconnect();
    }

    // this class implements jsch UserInfo interface for passing password to the session
    static class SSHUserInfo implements UserInfo {
        private String password;

        SSHUserInfo(String password) {
            this.password = password;
        }

        public String getPassphrase() {
            return null;
        }

        public String getPassword() {
            return password;
        }

        public boolean promptPassword(String arg0) {
            return true;
        }

        public boolean promptPassphrase(String arg0) {
            return true;
        }

        public boolean promptYesNo(String arg0) {
            return true;
        }

        public void showMessage(String arg0) {
            System.out.println(arg0);
        }
    }

}

19 Ekim 2011 Çarşamba

Pulling object array with multiple threads from an Oracle table by row locking PL/SQL function

Sometimes we encounter a situation that we have many Java threads pulling a record list from an Oracle table via JDBC continuously and process them in any manner. In these situations we may want such a case that one record should be selected by only one thread so that it can be processed only once. Then we meet with this solution:

Select the records which are not selected before with locking them and update their status as selected so that they can not be selected by different thread again.

In the example below i tried to show how to overcome such a problem with a locking cursor. The variables in curly brackets can be customized. They can be your own objects.
CREATE OR REPLACE FUNCTION pull_records return {new collection of object type} is
rowidarr      {new collection of varchar2};
recordarr     {new collection of object type};

CURSOR curpull IS SELECT ROWIDTOCHAR(ROWID) FROM {TABLE_NAME} where {pulled_before = false} FOR UPDATE NOWAIT SKIP LOCKED;

begin
    OPEN curpull();
    FETCH curpull BULK COLLECT INTO rowidarr LIMIT 1;
    CLOSE curpull;
    
    IF rowidarr IS NULL THEN
      rowidarr := {new table of varchar2};
    END IF;   

    -- update pulled records as pulled_before so that they are not selected in the next cycle
    FORALL i IN NVL(rowidarr.FIRST, 1) .. NVL(rowidarr.LAST, -1)
      UPDATE {TABLE_NAME} e SET {e.pulled_before = true} WHERE ROWID = CHARTOROWID(rowidarr(i))   RETURNING value(e) BULK COLLECT INTO recordarr;
    
    -- if recordarr is null then return an empty array 
    IF recordarr IS NULL THEN
      recordarr := {new collection of object type};
    END IF;
    
    COMMIT;
    return recordarr;
    
    EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
end;


The key section in the code above is FOR UPDATE NOWAIT SKIP LOCKED. This does the job for us. It locks the selected rows and we update the indicator field after locking. Then after committing, the rows are free with their new selected before statuses :)) So the other threads never see them in the "not pulled" state.

14 Ekim 2011 Cuma

Spring Security 3.0.5.RELEASE & Secure LDAP Integration

Spring security provides us lots of abilities for different types of authentication meschanisms. LDAP is one of them and in the example below i will try to show how to configure Spring for secure LDAP authentication.

Firstly let us look at our application-context.xml and beans that we should create:

   
   
   


We define a DefaultSpringSecurityContextSource bean which is our security context. For secure LDAP we should have a URL like this: ldaps://ldapServerUrl:636/dc=entp,dc=tgc
636 is the default port for LDAPS. User dn is custom and its format can be like: uid=LDAPSUSER,ou=SpecialUsers,dc=entp,dc=tgc.

Then our second bean is LdapAuthenticationProvider which does the real authentication job.

   
      
         
         
            
               uid={0},ou=People,o=[organizationName]
            
         
      
   
   
      
          
          
          
      
   


Be careful about userDnPatterns for determining the [organizationName].
At last, we define the authentication manager and we are ready for LDAPS authentication.

     


13 Ekim 2011 Perşembe

Reading formatted messages and extracting the real data coming through TCP socket

If the channel is kept alive between a client and a server then it is good to obey a messaging format for the communication between client and the server. Generally the obeyed format of the message can be as stated below:

START FLAG + LENGTH OF THE MESSAGE + MESSAGE BYTES + STOP FLAG

In the example below the start flag is assigned as 111999 and the stop flag is 999111. The server listens one or more clients and the reader threads extract the real messages coming from the clients. The method readUntilFlag does the real job for extracting the message.
package test;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class Application {

    public static void main(String[] args) throws IOException {
        int serverPort = 1111;
        ServerSocket serverSocket = new ServerSocket(serverPort);
        int clientId = 1;
        while (true) {
            Socket socket = serverSocket.accept();
            new ReaderThread(clientId++, socket).start();
        }
    }

    static class ReaderThread extends Thread{
        private int clientId;
        private Socket socket;

        ReaderThread(int clientId, Socket socket) {
            this.clientId = clientId;
            this.socket = socket;
        }

        public void run(){
            String message = null;
            while (!"exit".equalsIgnoreCase(message)) {
                try {
                    DataInputStream inputStream = new DataInputStream(socket.getInputStream());
                    readUntilFlag(inputStream, 111999);

                    int messageLength = inputStream.readInt();
                    byte[] messageBytes = new byte[messageLength];
                    inputStream.read(messageBytes, 0, messageLength);

                    readUntilFlag(inputStream, 999111);
                    message = new String(messageBytes);
                    System.out.println("Client " + clientId + " sent message: " + message + " to server...");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void readUntilFlag(DataInputStream inputStream, int flag) {
        boolean found = false;
        byte[] flagBytes = intToByteArray(flag);
        try {
            byte tempBytes[] = new byte[4];
            tempBytes[0] = inputStream.readByte();
            tempBytes[1] = inputStream.readByte();
            tempBytes[2] = inputStream.readByte();
            tempBytes[3] = inputStream.readByte();
            // read until the flag is found
            while (!found) {
                if (flagBytes[0] == tempBytes[0] &&
                    flagBytes[1] == tempBytes[1] &&
                    flagBytes[2] == tempBytes[2] &&
                    flagBytes[3] == tempBytes[3]) {
                    found = true;
                } else {
                    tempBytes[0] = tempBytes[1];
                    tempBytes[1] = tempBytes[2];
                    tempBytes[2] = tempBytes[3];
                    tempBytes[3] = inputStream.readByte();
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static byte[] intToByteArray(int value) {
        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            int offset = (b.length - 1 - i) * 8;
            b[i] = (byte) ((value >>> offset) & 0xFF);
        }
        return b;
    }
}