[SNMP4J] (WIP) SNMP4J CommonJ/Spring integration contrib, round 4

Brice Fines bfines at sermepa.es
Tue Mar 16 18:05:59 CET 2010


Hi everybody,

I made some fixes to my ThreadFactory based on Spring TaskExecutor. Now, 
interrupt/join/terminate calls are forwarded to the wrapped WorkerTask.
This way, threads close smoothly, without throwing errors.

I include my current code. Tested with SNMP4J 1.10.2 and Spring 
2.5.6-SEC01.
Comments and suggestions are welcome.
Next post will be for TimerFactory with CommonJ integration.

Regards


package org.snmp4j.util.spring;

import org.snmp4j.log.LogAdapter;
import org.snmp4j.log.LogFactory;
import org.snmp4j.util.ThreadFactory;
import org.snmp4j.util.WorkerTask;
import org.springframework.core.task.TaskExecutor;
import org.springframework.util.Assert;

/**
 * TreadFactory implementation based on Spring TaskExecutor.
 */
public class TaskExecutorThreadFactoryImpl implements ThreadFactory {

        /**
         * Logger.
         */
        final static LogAdapter LOGGER = LogFactory
                        .getLogger(TaskExecutorThreadFactoryImpl.class);

        /**
         * TaskExecutor.
         */
        private TaskExecutor taskExecutor;

        /**
         * Set TaskExecutor.
         * 
         * @param taskExecutor
         *            a TaskExecutor.
         */
        public void setTaskExecutor(TaskExecutor taskExecutor) {
                this.taskExecutor = taskExecutor;
        }

        /**
         * Constructor.
         */
        public TaskExecutorThreadFactoryImpl() {
        }

        /*
         * (without Javadoc)
         * 
         * @see 
org.snmp4j.util.ThreadFactory#createWorkerThread(java.lang.String,
         *      org.snmp4j.util.WorkerTask, boolean)
         */
        public WorkerTask createWorkerThread(String name, WorkerTask task,
                        boolean daemon) {
                LOGGER.debug("Creating WorkerThread: " + name + " daemon: 
" + daemon);
                return new TaskExecutorWorkerTaskImpl(taskExecutor, name, 
task,
                                daemon);
        }

        /**
         * Initialization.
         */
        public void init() {
                Assert.notNull(taskExecutor, "taskExecutor is required.");
        }

}



package org.snmp4j.util.spring;

import org.snmp4j.log.LogAdapter;
import org.snmp4j.log.LogFactory;
import org.snmp4j.util.WorkerTask;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.SchedulingAwareRunnable;

/**
 * WorkerTask implementation based on Spring TaskExecutor.
 */
public class TaskExecutorWorkerTaskImpl implements WorkerTask {

        /**
         * Logger.
         */
        final static LogAdapter LOGGER = LogFactory
                        .getLogger(TaskExecutorWorkerTaskImpl.class);

        /**
         * TaskExecutor.
         */
        private TaskExecutor taskExecutor;

        /**
         * Name.
         */
        private String name;

        /**
         * Worker task wrapper.
         */
        private WorkerTaskWrapper workerTaskWrapper;

        /**
         * Constructor.
         * 
         * @param taskExecutor
         *            a task executor.
         * @param name
         *            a name.
         * @param workerTask
         *            a worker task.
         * @param daemon
         *            true if daemon process, false otherwise.
         */
        public TaskExecutorWorkerTaskImpl(TaskExecutor taskExecutor,
                        String name, WorkerTask workerTask, boolean 
daemon) {
                this.taskExecutor = taskExecutor;
                this.name = name;
                this.workerTaskWrapper = new WorkerTaskWrapper(workerTask, 
daemon);
        }

        /*
         * (withoutJavadoc)
         * 
         * @see org.snmp4j.util.WorkerTask#interrupt()
         */
        public void interrupt() {
                LOGGER.debug("WorkerTask interrupt: " + this.name);
                workerTaskWrapper.workerTask.interrupt();
        }

        /*
         * (withoutJavadoc)
         * 
         * @see org.snmp4j.util.WorkerTask#join()
         */
        public void join() throws InterruptedException {
                LOGGER.debug("WorkerTask join: " + this.name);
                workerTaskWrapper.workerTask.join();
        }

        /*
         * (withoutJavadoc)
         * 
         * @see org.snmp4j.util.WorkerTask#terminate()
         */
        public void terminate() {
                LOGGER.debug("WorkerTask terminate: " + this.name);
                workerTaskWrapper.workerTask.terminate();
        }

        /*
         * (withoutJavadoc)
         * 
         * @see java.lang.Runnable#run()
         */
        public void run() {
                LOGGER.debug("WorkerTask run: " + this.name);
                taskExecutor.execute(workerTaskWrapper);
        }

        /**
         * Wrapper for WorkerTask.
         * 
         */
        private class WorkerTaskWrapper implements SchedulingAwareRunnable 
{

                /**
                 * Worker task.
                 */
                private WorkerTask workerTask;

                /**
                 * True if daemon process, false otherwise.
                 */
                private boolean daemon;

                /**
                 * Constructor.
                 * 
                 * @param workerTask
                 *            a worker task.
                 * @param daemon
                 *            true if daemon process, false otherwise.
                 */
                public WorkerTaskWrapper(WorkerTask workerTask, boolean 
daemon) {
                        this.workerTask = workerTask;
                        this.daemon = daemon;
                }

                /*
                 * (without Javadoc)
                 * 
                 * @see java.lang.Runnable#run()
                 */
                public void run() {
                        workerTask.run();
                }

                /*
                 * (without Javadoc)
                 * 
                 * @see 
org.springframework.scheduling.SchedulingAwareRunnable#isLongLived()
                 */
                public boolean isLongLived() {
                        return daemon;
                }

        }
}



Extract from application context:

        <bean id="taskExecutor"
                class=
"org.springframework.scheduling.commonj.WorkManagerTaskExecutor"
                p:workManagerName="yourWorkManagerReferenceName" 
p:resourceRef="true" />

        <bean id="snmp4jThreadFactory"
                class=
"org.snmp4j.util.spring.TaskExecutorThreadFactoryImpl"
                init-method="init" p:taskExecutor-ref="taskExecutor" />

You need a work manager defined in your application server, and a 
reference defined in your web.xml for it.





More information about the SNMP4J mailing list