Package er.changenotification

Source Code of er.changenotification.ERCNConnectionKeeper

//
// ERCNNotificationCoordinator.java
// Project ERChangeNotificationJMS
//
// Created by tatsuya on Sat Mar 6 2004
//
package er.changenotification;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import javax.jms.ConnectionMetaData;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;

import com.webobjects.foundation.NSLog;
import com.webobjects.foundation.NSTimestamp;

class ERCNConnectionKeeper implements ExceptionListener {

    public static final boolean VERBOSE_LOGGING = true;
    public static final boolean QUIET_LOGGING = false;

    private ERCNNotificationCoordinator _coordinator;
    private Timer _recoveryTimer;

    private Topic _topic;
    private TopicConnection _connection;

    private boolean _isConnected = false;

    ERCNConnectionKeeper(ERCNNotificationCoordinator coordinator) {
        _coordinator = coordinator;
    }

    // Open the connection to the JMS server.
    void openConnection(boolean verboseLogging) {
        if (_isConnected) {
            stopConnection(QUIET_LOGGING);
            closeConnection(QUIET_LOGGING);
            _isConnected = false;
        }

        Properties properties = _coordinator.configuration().jmsProperties();
        //NSLog.debug.appendln(ERCNNotificationCoordinator.LOG_HEADER + "properties: " + properties);

        TopicConnectionFactory connectionFactory = null;
        try {
            Context context = new InitialContext(properties);
            connectionFactory = (TopicConnectionFactory) context.lookup("JmsTopicConnectionFactory");
            _topic = (Topic) context.lookup(_coordinator.configuration().topicName());
        } catch (CommunicationException ex) {
            // javax.naming.CommunicationException -- no JNDI server
            if (verboseLogging) {
                NSLog.err.appendln(ERCNNotificationCoordinator.LOG_HEADER
                        + "Cannot connect to the JNDI server. Please check if the JNDI server is available: "
                        + ex.getMessage());
            }
            return;
        } catch (NameNotFoundException ex) {
            // javax.naming.NameNotFoundException -- no topic
            throw new RuntimeException("Cannot find the topic with name \"" + _coordinator.configuration().topicName() + "\"."
                    + "Please check if the JMS server is properly configured: " + ex.getMessage());
        } catch (NamingException ex) {
            if (verboseLogging) {
                NSLog.err.appendln(ERCNNotificationCoordinator.LOG_HEADER
                        + "An exception occurred while locating the topic with JNDI server: " + ex.getMessage());
            }
            return;
        }

        String providerName = null;
        String providerVersion = null;
        try {
            _connection = connectionFactory.createTopicConnection();
            ConnectionMetaData metaData = _connection.getMetaData();
            providerName = metaData.getJMSProviderName();
            providerVersion = metaData.getProviderVersion();

            // Set itself as the exception listener.
            _connection.setExceptionListener(this);

        } catch (JMSException ex) {
            if (verboseLogging) {
                NSLog.err.appendln(ERCNNotificationCoordinator.LOG_HEADER
                        + "An exception occured while creating a JMS connection: " + ex.getMessage());
            }
            return;
        }

        try {
            _connection.start();
            _coordinator.didConnect(_connection);
        } catch (JMSException ex) {
            if (verboseLogging) {
                NSLog.err.appendln(ERCNNotificationCoordinator.LOG_HEADER
                        + "An exception occured while starting the JMS connection : " + ex.getMessage());
                ex.printStackTrace();
            }
            return;
        }

        NSLog.out.appendln(ERCNNotificationCoordinator.LOG_HEADER + "Connected to the JMS server: "
                + providerName + " " + providerVersion);

        _isConnected = true;
    }

    void stopConnection(boolean verboseLogging) {
        if (_connection == null)   return;

        try {
            _connection.stop();
         } catch (JMSException ex) {
            if (verboseLogging) {
                NSLog.err.appendln(ERCNNotificationCoordinator.LOG_HEADER
                        + "An exception occured while stopping the JMS connection: " + ex.getMessage());
            }
        }
    }

    void closeConnection(boolean verboseLogging) {
        if (_connection == null)   return;

        try {
            _connection.close();
        } catch (JMSException ex) {
            if (verboseLogging) {
                NSLog.err.appendln(ERCNNotificationCoordinator.LOG_HEADER
                    + "An exception occured while closing the JMS connection    : " + ex.getMessage());
            }
        }
    }

    void initiateRecoveryTask() {

        NSLog.out.appendln(ERCNNotificationCoordinator.LOG_HEADER + ": Trying to connect to the JMS Server... "
                + "(Recovery interval: " + _coordinator.configuration().connectionRecoveryInterval() + " seconds)");

        if (_recoveryTimer != null)
            _recoveryTimer.cancel();

        _recoveryTimer = new Timer(true);

        // This TimerTask trys to recover the JMS connection.
        TimerTask recoveryTask = new TimerTask() {

            @Override
            public void run() {
                openConnection(QUIET_LOGGING);
                if (isConnected())
                    _recoveryTimer.cancel();
            }

        };

        // This TimerTask displays warning messages.
        TimerTask warningMessageTask = new TimerTask() {

            private NSTimestamp _downTime = new NSTimestamp();
            private String _downTimeString = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(_downTime);

            @Override
            public void run() {
                if (! _isConnected) {
                    double elapsTime = (new NSTimestamp().getTime() - _downTime.getTime()) / (60.0d * 60.0d * 1000.0d);
                    String elapsTimeString = new DecimalFormat("#,##0.0").format(elapsTime);

                    NSLog.err.appendln(ERCNNotificationCoordinator.LOG_HEADER
                            + "JMS connection has been down for " + elapsTimeString + " hours. "
                            + "(Since " + _downTimeString + ")");
                }
            }

        };

        long recoveryIntervalMils = _coordinator.configuration().connectionRecoveryInterval() * 1000;
        _recoveryTimer.scheduleAtFixedRate(recoveryTask, recoveryIntervalMils, recoveryIntervalMils);

        long warningIntervalMils = _coordinator.configuration().disconnectionWarningInterval() * 1000;
        _recoveryTimer.scheduleAtFixedRate(warningMessageTask, warningIntervalMils, warningIntervalMils);

    }

    public void onException(JMSException exception) {
        NSLog.err.appendln(ERCNNotificationCoordinator.LOG_HEADER
                + "Connection Keeper has detected a problem with the current JMS connection: "
                + exception.getMessage());

        _isConnected = false;

        stopConnection(QUIET_LOGGING);
        _coordinator.didDisconnect(_connection);

        closeConnection(QUIET_LOGGING);

        _topic = null;
        _connection = null;

        initiateRecoveryTask();
    }

    Topic topic() {
        return _topic;
    }

    TopicConnection connection() {
        return _connection;
    }

    boolean isConnected() {
        return _isConnected;
    }

    synchronized void terminate() {
        // do nothing
    }

}
TOP

Related Classes of er.changenotification.ERCNConnectionKeeper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.