Search in sources :

Example 16 with HABrokerInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo in project openmq by eclipse-ee4j.

the class BrokerDAOImpl method takeover.

/**
 * Update the state and other relevant attributes of a broker to signify the store is being taken over by another
 * broker. If the operation is successful then this means that the current broker was able to acquire the lock and it is
 * now responsible for taken over the store of the target broker.
 *
 * @param conn database connection
 * @param id the current or local broker ID
 * @param targetBrokerID the broker ID of the store being taken over
 * @param lastHeartbeat broker's last heartbeat
 * @param expectedState the expected state
 * @param newHeartbeat the new timestamp
 * @param newState the new state
 * @throws TakeoverLockException if the current broker is unable to acquire the takeover lock
 * @return previous broker's info associated with the broker
 */
@Override
public HABrokerInfo takeover(Connection conn, String id, String targetBrokerID, long lastHeartbeat, BrokerState expectedState, long newHeartbeat, BrokerState newState) throws BrokerException {
    HABrokerInfo bkrInfo = null;
    PreparedStatement pstmt = null;
    Exception myex = null;
    try {
        // Save the broker's state before updating
        bkrInfo = getBrokerInfo(conn, targetBrokerID);
        if (bkrInfo == null) {
            String errorMsg = br.getKString(BrokerResources.E_BROKERINFO_NOT_FOUND_IN_STORE, targetBrokerID);
            throw new BrokerException(br.getKString(BrokerResources.E_INTERNAL_BROKER_ERROR, errorMsg));
        }
        DBManager dbMgr = DBManager.getDBManager();
        pstmt = dbMgr.createPreparedStatement(conn, takeoverSQL);
        pstmt.setString(1, id);
        pstmt.setInt(2, newState.intValue());
        pstmt.setLong(3, newHeartbeat);
        pstmt.setString(4, targetBrokerID);
        pstmt.setInt(5, expectedState.intValue());
        pstmt.setLong(6, lastHeartbeat);
        if (pstmt.executeUpdate() != 1) {
            HABrokerInfo binfo = getBrokerInfo(conn, targetBrokerID);
            String errorMsg = br.getKString(BrokerResources.E_UNABLE_TO_ACQUIRE_TAKEOVER_LOCK, targetBrokerID);
            TakeoverLockException ex = new TakeoverLockException(errorMsg);
            // Store broker info
            ex.setBrokerInfo(binfo);
            throw ex;
        }
    } catch (Exception e) {
        myex = e;
        try {
            if ((conn != null) && !conn.getAutoCommit()) {
                conn.rollback();
            }
        } catch (SQLException rbe) {
            logger.log(Logger.ERROR, BrokerResources.X_DB_ROLLBACK_FAILED, rbe);
        }
        Exception ex;
        if (e instanceof BrokerException) {
            throw (BrokerException) e;
        } else if (e instanceof SQLException) {
            ex = DBManager.wrapSQLException("[" + takeoverSQL + "]", (SQLException) e);
        } else {
            ex = e;
        }
        throw new BrokerException(br.getKString(BrokerResources.E_UNABLE_TO_TAKEOVER_BROKER, targetBrokerID), ex);
    } finally {
        Util.close(null, pstmt, null, myex);
    }
    return bkrInfo;
}
Also used : HABrokerInfo(com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo) TakeoverLockException(com.sun.messaging.jmq.jmsserver.persist.api.TakeoverLockException) TakeoverLockException(com.sun.messaging.jmq.jmsserver.persist.api.TakeoverLockException)

Example 17 with HABrokerInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo in project openmq by eclipse-ee4j.

the class ConsumerStateDAOImpl method updateTransaction.

/**
 * Update existing entry.
 *
 * @param conn database connection
 * @param sysMsgID the system message ID
 * @param conUID the consumer id
 * @param txnUID the transaction id associated with an acknowledgment
 */
@Override
public void updateTransaction(Connection conn, SysMessageID sysMsgID, ConsumerUID conUID, TransactionUID txnUID) throws BrokerException {
    String msgID = sysMsgID.getUniqueName();
    boolean myConn = false;
    PreparedStatement pstmt = null;
    Exception myex = null;
    String sql = updateTransactionSQL;
    try {
        // Get a connection
        DBManager dbMgr = DBManager.getDBManager();
        if (conn == null) {
            conn = dbMgr.getConnection(true);
            myConn = true;
        }
        // Make sure the transaction exists
        dbMgr.getDAOFactory().getTransactionDAO().checkTransaction(conn, txnUID.longValue());
        pstmt = dbMgr.createPreparedStatement(conn, sql);
        pstmt.setLong(1, txnUID.longValue());
        pstmt.setString(2, msgID);
        pstmt.setLong(3, conUID.longValue());
        if (Globals.getHAEnabled()) {
            pstmt.setString(4, dbMgr.getBrokerID());
        }
        if (pstmt.executeUpdate() == 0) {
            // For HA mode, check if this broker still owns the store
            if (Globals.getHAEnabled()) {
                String brokerID = dbMgr.getBrokerID();
                BrokerDAO dao = dbMgr.getDAOFactory().getBrokerDAO();
                if (dao.isBeingTakenOver(conn, brokerID)) {
                    BrokerException be = new StoreBeingTakenOverException(br.getKString(BrokerResources.E_STORE_BEING_TAKEN_OVER));
                    try {
                        HABrokerInfo bkrInfo = dao.getBrokerInfo(conn, brokerID);
                        logger.logStack(Logger.ERROR, be.getMessage() + "[" + (bkrInfo == null ? "" + brokerID : bkrInfo.toString()) + "]", be);
                    } catch (Throwable t) {
                    /* Ignore error */
                    }
                    throw be;
                }
            }
            // Check if ack exists
            long existingTxnId = getTransaction(conn, sysMsgID, conUID);
            if (existingTxnId > 0) {
                TransactionUID oldTxnUID = new TransactionUID(existingTxnId);
                TransactionState ts = dbMgr.getDAOFactory().getTransactionDAO().getTransactionState(conn, oldTxnUID);
                String[] args = { "[" + sysMsgID + ", " + conUID + "]", oldTxnUID + "[" + ts + "]", txnUID.toString() };
                logger.log(logger.WARNING, br.getKString(BrokerResources.W_STORE_TXN_ACK_EXIST, args));
                // message can be redelivered but rollback transaction failed
                updateTransactionNoCheck(conn, sysMsgID, conUID, txnUID);
                return;
            }
            // We're assuming the entry does not exist
            throw new BrokerException(br.getKString(BrokerResources.E_INTEREST_STATE_NOT_FOUND_IN_STORE, conUID.toString(), msgID), Status.NOT_FOUND);
        }
    } catch (Exception e) {
        myex = e;
        try {
            if ((conn != null) && !conn.getAutoCommit()) {
                conn.rollback();
            }
        } catch (SQLException rbe) {
            logger.log(Logger.ERROR, BrokerResources.X_DB_ROLLBACK_FAILED + "[" + sql + "]", rbe);
        }
        Exception ex;
        if (e instanceof BrokerException) {
            throw (BrokerException) e;
        } else if (e instanceof SQLException) {
            ex = DBManager.wrapSQLException("[" + sql + "]", (SQLException) e);
        } else {
            ex = e;
        }
        throw new BrokerException(br.getKString(BrokerResources.X_PERSIST_INTEREST_STATE_FAILED, conUID.toString(), sysMsgID.toString()), ex);
    } finally {
        if (myConn) {
            Util.close(null, pstmt, conn, myex);
        } else {
            Util.close(null, pstmt, null, myex);
        }
    }
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) HABrokerInfo(com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID)

Example 18 with HABrokerInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo in project openmq by eclipse-ee4j.

the class ConsumerStateDAOImpl method updateTransactionNoCheck.

private void updateTransactionNoCheck(Connection conn, SysMessageID sysMsgID, ConsumerUID conUID, TransactionUID txnUID) throws BrokerException {
    String msgID = sysMsgID.getUniqueName();
    boolean myConn = false;
    PreparedStatement pstmt = null;
    Exception myex = null;
    String sql = updateTransactionNoCheckSQL;
    try {
        // Get a connection
        DBManager dbMgr = DBManager.getDBManager();
        if (conn == null) {
            conn = dbMgr.getConnection(true);
            myConn = true;
        }
        // Make sure the transaction exists
        dbMgr.getDAOFactory().getTransactionDAO().checkTransaction(conn, txnUID.longValue());
        pstmt = dbMgr.createPreparedStatement(conn, sql);
        pstmt.setLong(1, txnUID.longValue());
        pstmt.setString(2, msgID);
        pstmt.setLong(3, conUID.longValue());
        pstmt.setLong(4, txnUID.longValue());
        if (Globals.getHAEnabled()) {
            pstmt.setString(5, dbMgr.getBrokerID());
        }
        if (pstmt.executeUpdate() == 0) {
            if (Globals.getHAEnabled()) {
                String brokerID = dbMgr.getBrokerID();
                BrokerDAO dao = dbMgr.getDAOFactory().getBrokerDAO();
                if (dao.isBeingTakenOver(conn, brokerID)) {
                    BrokerException be = new StoreBeingTakenOverException(br.getKString(BrokerResources.E_STORE_BEING_TAKEN_OVER));
                    try {
                        HABrokerInfo bkrInfo = dao.getBrokerInfo(conn, brokerID);
                        logger.logStack(Logger.ERROR, be.getMessage() + "[" + (bkrInfo == null ? "" + brokerID : bkrInfo.toString()) + "]", be);
                    } catch (Throwable t) {
                    /* Ignore error */
                    }
                    throw be;
                }
            }
            long existingTxnId = getTransaction(conn, sysMsgID, conUID);
            if (existingTxnId > 0) {
                TransactionUID oldTxnUID = new TransactionUID(existingTxnId);
                TransactionState ts = dbMgr.getDAOFactory().getTransactionDAO().getTransactionState(conn, oldTxnUID);
                String[] args = { "[" + sysMsgID + ", " + conUID + "]TID=" + oldTxnUID + "(" + ts + ")", txnUID.toString() };
                throw new BrokerException(br.getKString(br.E_ACK_EXISTS_IN_STORE, args));
            }
            throw new BrokerException(br.getKString(BrokerResources.E_INTEREST_STATE_NOT_FOUND_IN_STORE, conUID.toString(), msgID), Status.NOT_FOUND);
        }
    } catch (Exception e) {
        myex = e;
        try {
            if ((conn != null) && !conn.getAutoCommit()) {
                conn.rollback();
            }
        } catch (SQLException rbe) {
            logger.log(Logger.ERROR, BrokerResources.X_DB_ROLLBACK_FAILED + "[" + sql + "]", rbe);
        }
        Exception ex;
        if (e instanceof BrokerException) {
            throw (BrokerException) e;
        } else if (e instanceof SQLException) {
            ex = DBManager.wrapSQLException("[" + sql + "]", (SQLException) e);
        } else {
            ex = e;
        }
        throw new BrokerException(br.getKString(BrokerResources.X_PERSIST_INTEREST_STATE_FAILED, conUID.toString(), sysMsgID.toString()), ex);
    } finally {
        if (myConn) {
            Util.close(null, pstmt, conn, myex);
        } else {
            Util.close(null, pstmt, null, myex);
        }
    }
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) HABrokerInfo(com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID)

Example 19 with HABrokerInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo in project openmq by eclipse-ee4j.

the class ConsumerStateDAOImpl method updateState.

/**
 * Update existing entry.
 *
 * @param conn database connection
 * @param dstUID the destination ID
 * @param sysMsgID the system message ID
 * @param conUID the consumer id
 * @param state the state
 */
@Override
public void updateState(Connection conn, DestinationUID dstUID, SysMessageID sysMsgID, ConsumerUID conUID, int state, boolean replaycheck) throws BrokerException {
    String msgID = sysMsgID.getUniqueName();
    boolean myConn = false;
    PreparedStatement pstmt = null;
    Exception myex = null;
    try {
        // Get a connection
        DBManager dbMgr = DBManager.getDBManager();
        if (conn == null) {
            conn = dbMgr.getConnection(true);
            myConn = true;
        }
        // Get the broker ID of the msg which also checks if the msg exists
        String brokerID = null;
        if (Globals.getHAEnabled()) {
            try {
                brokerID = dbMgr.getDAOFactory().getMessageDAO().getBroker(conn, dstUID, msgID);
            } catch (BrokerException e) {
                if (e.getStatusCode() != Status.NOT_FOUND) {
                    e.setSQLRecoverable(true);
                    e.setSQLReplayCheck(replaycheck);
                }
                throw e;
            }
        } else {
            brokerID = dbMgr.getBrokerID();
        }
        if (replaycheck) {
            try {
                int currstate = getState(conn, sysMsgID, conUID);
                if (currstate == state) {
                    logger.log(Logger.INFO, BrokerResources.I_CANCEL_SQL_REPLAY, msgID + "[" + dstUID + "]" + conUID + ":" + state);
                    return;
                }
            } catch (BrokerException e) {
                if (e.getStatusCode() != Status.NOT_FOUND) {
                    e.setSQLRecoverable(true);
                    e.setSQLReplayCheck(true);
                }
                throw e;
            }
        }
        // For HA, state can only be udpated by the broker that owns the msg
        if (Globals.getHAEnabled() && !dbMgr.getBrokerID().equals(brokerID)) {
            String emsg = br.getKString(BrokerResources.X_PERSIST_INTEREST_STATE_FAILED, conUID.toString(), sysMsgID.toString());
            BrokerException be = new StoreBeingTakenOverException(br.getKString(BrokerResources.E_STORE_BEING_TAKEN_OVER + "[" + emsg + "]"));
            try {
                BrokerDAO dao = dbMgr.getDAOFactory().getBrokerDAO();
                HABrokerInfo bkrInfo = dao.getBrokerInfo(conn, dbMgr.getBrokerID());
                logger.logStack(Logger.ERROR, be.getMessage() + "[" + (bkrInfo == null ? "" + dbMgr.getBrokerID() : bkrInfo.toString()) + "]", be);
            } catch (Throwable t) {
            /* Ignore error */
            }
            throw be;
        }
        pstmt = dbMgr.createPreparedStatement(conn, updateStateSQL);
        pstmt.setInt(1, state);
        pstmt.setString(2, msgID);
        pstmt.setLong(3, conUID.longValue());
        if (pstmt.executeUpdate() == 0) {
            // Otherwise we're assuming the entry does not exist
            throw new BrokerException(br.getKString(BrokerResources.E_INTEREST_STATE_NOT_FOUND_IN_STORE, conUID.toString(), msgID), Status.NOT_FOUND);
        }
    } catch (Exception e) {
        myex = e;
        boolean replayck = false;
        try {
            if ((conn != null) && !conn.getAutoCommit()) {
                conn.rollback();
            }
        } catch (SQLException rbe) {
            replayck = true;
            logger.log(Logger.ERROR, BrokerResources.X_DB_ROLLBACK_FAILED, rbe);
        }
        Exception ex;
        if (e instanceof BrokerException) {
            throw (BrokerException) e;
        } else if (e instanceof SQLException) {
            ex = DBManager.wrapSQLException("[" + updateStateSQL + "]", (SQLException) e);
        } else {
            ex = e;
        }
        BrokerException be = new BrokerException(br.getKString(BrokerResources.X_PERSIST_INTEREST_STATE_FAILED, conUID.toString(), sysMsgID.toString()), ex);
        be.setSQLRecoverable(true);
        if (replayck) {
            be.setSQLReplayCheck(true);
        }
        throw be;
    } finally {
        if (myConn) {
            Util.close(null, pstmt, conn, myex);
        } else {
            Util.close(null, pstmt, null, myex);
        }
    }
}
Also used : HABrokerInfo(com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo)

Example 20 with HABrokerInfo

use of com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo in project openmq by eclipse-ee4j.

the class ConsumerStateDAOImpl method clearTransaction.

/**
 * Clear the transaction from all consumer states associated with it.
 *
 * @param conn Database Connection
 * @param txnUID the transaction
 */
@Override
public void clearTransaction(Connection conn, TransactionUID txnUID) throws BrokerException {
    long txnID = txnUID.longValue();
    boolean myConn = false;
    PreparedStatement pstmt = null;
    Exception myex = null;
    try {
        if (FI.FAULT_INJECTION) {
            HashMap m = new HashMap();
            m.put(FaultInjection.FAULT_COUNT_PROP, String.valueOf(faultCount));
            if (FI.checkFault(FI.FAULT_TXN_ROLLBACK_DBCONSTATE_CLEARTID, m)) {
                faultCount++;
                throw new BrokerException("FAULT INJECTION:" + FI.FAULT_TXN_ROLLBACK_DBCONSTATE_CLEARTID);
            }
        }
        // Get a connection
        DBManager dbMgr = DBManager.getDBManager();
        if (conn == null) {
            conn = dbMgr.getConnection(true);
            myConn = true;
        }
        pstmt = dbMgr.createPreparedStatement(conn, clearTxnSQL);
        pstmt.setLong(1, txnID);
        if (Globals.getHAEnabled()) {
            pstmt.setString(2, dbMgr.getBrokerID());
        }
        if (pstmt.executeUpdate() == 0) {
            // For HA mode, check if this broker still owns the store
            if (Globals.getHAEnabled()) {
                String brokerID = dbMgr.getBrokerID();
                BrokerDAO dao = dbMgr.getDAOFactory().getBrokerDAO();
                if (dao.isBeingTakenOver(conn, brokerID)) {
                    BrokerException be = new StoreBeingTakenOverException(br.getKString(BrokerResources.E_STORE_BEING_TAKEN_OVER));
                    try {
                        HABrokerInfo bkrInfo = dao.getBrokerInfo(conn, brokerID);
                        logger.logStack(Logger.ERROR, be.getMessage() + ": " + bkrInfo.toString(), be);
                        be.setStackLogged();
                    } catch (Throwable t) {
                    /* Ignore error */
                    }
                    throw be;
                }
            }
        }
    } catch (Exception e) {
        myex = e;
        try {
            if ((conn != null) && !conn.getAutoCommit()) {
                conn.rollback();
            }
        } catch (SQLException rbe) {
            logger.log(Logger.ERROR, BrokerResources.X_DB_ROLLBACK_FAILED, rbe);
        }
        Exception ex;
        if (e instanceof BrokerException) {
            throw (BrokerException) e;
        } else if (e instanceof SQLException) {
            ex = DBManager.wrapSQLException("[" + clearTxnSQL + "]", (SQLException) e);
        } else {
            ex = e;
        }
        BrokerException be = new BrokerException(br.getKString(BrokerResources.X_CLEAR_TXN_FROM_INT_STATES_FAILED, txnUID), ex);
        be.setSQLRecoverable(true);
        throw be;
    } finally {
        if (myConn) {
            Util.close(null, pstmt, conn, myex);
        } else {
            Util.close(null, pstmt, null, myex);
        }
    }
}
Also used : HABrokerInfo(com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo)

Aggregations

HABrokerInfo (com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo)28 HAClusteredBroker (com.sun.messaging.jmq.jmsserver.cluster.api.ha.HAClusteredBroker)6 TakeoverLockException (com.sun.messaging.jmq.jmsserver.persist.api.TakeoverLockException)6 HashMap (java.util.HashMap)5 AutoClusterBrokerMap (com.sun.messaging.jmq.jmsserver.cluster.manager.AutoClusterBrokerMap)4 TransactionUID (com.sun.messaging.jmq.jmsserver.data.TransactionUID)4 Iterator (java.util.Iterator)4 Map (java.util.Map)4 TransactionState (com.sun.messaging.jmq.jmsserver.data.TransactionState)3 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)3 IOException (java.io.IOException)3 JMSBridgeStore (com.sun.messaging.bridge.api.JMSBridgeStore)2 InvalidPacketException (com.sun.messaging.jmq.io.InvalidPacketException)2 Packet (com.sun.messaging.jmq.io.Packet)2 PacketReadEOFException (com.sun.messaging.jmq.io.PacketReadEOFException)2 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)2 Consumer (com.sun.messaging.jmq.jmsserver.core.Consumer)2 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)2 Destination (com.sun.messaging.jmq.jmsserver.core.Destination)2 DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)2