Package com.trendmicro.mist

Source Code of com.trendmicro.mist.MigrateEntry

package com.trendmicro.mist;

import java.util.ArrayList;
import java.util.concurrent.TimeoutException;

import javax.jms.ConnectionFactory;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.trendmicro.mist.proto.GateTalk;
import com.trendmicro.mist.session.Session;
import com.trendmicro.mist.session.SessionPool;
import com.trendmicro.mist.util.ConnectionList;
import com.trendmicro.mist.util.Exchange;
import com.trendmicro.spn.common.FixedReconnect;
import com.trendmicro.spn.common.InfiniteReconnect;
import com.trendmicro.spn.common.ReconnectCounter;

public class Connection implements ExceptionListener {
    private GateTalk.Connection connectionConfig;
    private javax.jms.Connection connection = null;
    private ConnectionList connList = new ConnectionList();
    private int myId = -1;
    private static int connectionIdCnt = 0;
    private final static Logger logger = LoggerFactory.getLogger(Connection.class);
    private boolean connected = false;
    private int referenceCount = 0;
    private boolean isOpenMQCluster = false;

    private void createJMSConnection() throws MistException {
        try {
            tryConnect(new FixedReconnect(3, 150));
        }
        catch(MistException e) {
            throw e;
        }
    }

    private void closeJMSConnection() {
        if(connected) {
            try {
                connection.close();
                logger.info(String.format("%d: `%s' closed", getId(), getConnectionString()));
            }
            catch(JMSException e) {
                logger.error("can not close connection");
            }
            connected = false;
            connection = null;
        }
    }

    private void tryConnect(ReconnectCounter counter) throws MistException {
        if(connected)
            closeJMSConnection();

        counter.init();
        do {
            connected = false;
            try {
                String username = connectionConfig.getUsername();
                String password = connectionConfig.getPassword();
                if(username == null)
                    username = "";
                if(password == null)
                    password = "";
                try {
                    if(connectionConfig.getBrokerType().equals("openmq")) {
                        ConnectionFactory conn_fact = new com.sun.messaging.ConnectionFactory();
                        if(connList.size() == 1) {
                            ((com.sun.messaging.ConnectionFactory) conn_fact).setProperty(com.sun.messaging.ConnectionConfiguration.imqBrokerHostName, connList.get(0).getHost());
                            ((com.sun.messaging.ConnectionFactory) conn_fact).setProperty(com.sun.messaging.ConnectionConfiguration.imqBrokerHostPort, connList.get(0).getPort());
                        }
                        else if(connList.size() > 1) {
                            ((com.sun.messaging.ConnectionFactory) conn_fact).setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressList, connList.toString());
                            ((com.sun.messaging.ConnectionFactory) conn_fact).setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressListIterations, "-1");
                            ((com.sun.messaging.ConnectionFactory) conn_fact).setProperty(com.sun.messaging.ConnectionConfiguration.imqReconnectEnabled, "true");
                            ((com.sun.messaging.ConnectionFactory) conn_fact).setProperty(com.sun.messaging.ConnectionConfiguration.imqReconnectAttempts, "1");
                        }
                        ((com.sun.messaging.ConnectionFactory) conn_fact).setProperty(com.sun.messaging.ConnectionConfiguration.imqDefaultUsername, username);
                        ((com.sun.messaging.ConnectionFactory) conn_fact).setProperty(com.sun.messaging.ConnectionConfiguration.imqDefaultPassword, password);
                        connection = conn_fact.createConnection();
                    }
                }
                catch(JMSException e) {
                    throw e;
                }
                connection.setExceptionListener(this);
                connection.start();
                connected = true;
                logger.info(String.format("%d: `%s' connected. Current connected broker: %s", getId(), getConnectionString(), connection.toString()));
            }
            catch(JMSException e) {
                logger.error(String.format("%d: %s", getId(), e.getMessage()));
                if(Daemon.isShutdownRequested()) {
                    logger.warn("shutdown, abort re-connection");
                    break;
                }
                try {
                    counter.waitAndCheckCounter();
                    if(referenceCount <= 0) {
                        Daemon.connectionPool.remove(this);
                        break;
                    }
                }
                catch(TimeoutException e2) {
                    throw new MistException(String.format("reach re-connect limit %d, abort", counter.getCounter()));
                }
            }
        } while(connected == false);
    }

    private synchronized void reconnect() {
        logger.warn(String.format("Re-connecting (%d)", myId));
        try {
            tryConnect(new InfiniteReconnect());
        }
        catch(Exception e) {
            logger.error(e.getMessage(), e);
            logger.error("connection %d: fail to reconnect", myId);
            return;
        }

        class MigrateEntry {
            public Session sess;
            public Exchange ex;

            public MigrateEntry(Session sess, Exchange ex) {
                this.sess = sess;
                this.ex = ex;
            }
        }
        ArrayList<MigrateEntry> migrateList = new ArrayList<MigrateEntry>();

        for(Session sess : SessionPool.pool.values())
            if(sess.isAttached())
                for(Client client : sess.getClientList())
                    if(client.getConnection() == this)
                        migrateList.add(new MigrateEntry(sess, client.getExchange()));
        for(MigrateEntry ent : migrateList)
            ent.sess.migrateClient(ent.ex);
    }

    // //////////////////////////////////////////////////////////////////////////////

    public Connection(GateTalk.Connection conn_config) {
        connectionConfig = conn_config;
        connList.set(connectionConfig.getHostName(), connectionConfig.getHostPort());
        if(connectionConfig.getBrokerType().equals("openmq") && connList.size() > 1)
            isOpenMQCluster = true;
        myId = connectionIdCnt++;
    }

    public GateTalk.Connection getConfig() {
        return connectionConfig;
    }

    public String getType() {
        return connectionConfig.getBrokerType();
    }

    public javax.jms.Connection getJMSConnection() {
        return connection;
    }

    public void open() throws MistException {
        try {
            createJMSConnection();
        }
        catch(MistException e) {
            throw e;
        }
    }

    public void close() {
        closeJMSConnection();
    }

    public int getId() {
        return myId;
    }

    public boolean isConnected() {
        return connected;
    }

    public String getHostName() {
        return connectionConfig.getHostName();
    }

    public String getActiveBroker() {
        if(connectionConfig.getBrokerType().equals("openmq"))
            return ((com.sun.messaging.jms.Connection) connection).getBrokerAddress();
        else
            return "";
    }

    public String getConnectionString() {
        if(connList.size() > 1)
            return String.format("%s (active: %s)", connList.toString(), getActiveBroker());
        return connList.toString();
    }

    public boolean isOpenMQCluster() {
        return isOpenMQCluster;
    }

    public void onException(JMSException e) {
        logger.error(String.format("connection %d: received JMSException", getId()), e);
        reconnect();
    }

    public void increaseReference() {
        synchronized(Daemon.connectionPool) {
            referenceCount++;
        }
    }

    public void decreaseReference() {
        synchronized(Daemon.connectionPool) {
            referenceCount--;
            if(referenceCount == 0) {
                close();
                Daemon.connectionPool.remove(this);
            }
        }
    }

    public int getReferenceCount() {
        return referenceCount;
    }
}
TOP

Related Classes of com.trendmicro.mist.MigrateEntry

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.