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;
    }
}