Package com.sun.messaging.jmq.jmsserver.persist.jdbc

Source Code of com.sun.messaging.jmq.jmsserver.persist.jdbc.UpgradeStore

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2000-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

/*
* @(#)UpgradeStore.java  1.23 07/19/07
*/

package com.sun.messaging.jmq.jmsserver.persist.jdbc;

import com.sun.messaging.jmq.io.Packet;
import com.sun.messaging.jmq.io.SysMessageID;
import com.sun.messaging.jmq.util.log.Logger;
import com.sun.messaging.jmq.util.JMQXid;
import com.sun.messaging.jmq.jmsserver.core.*;
import com.sun.messaging.jmq.jmsserver.data.TransactionUID;
import com.sun.messaging.jmq.jmsserver.data.TransactionState;
import com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement;
import com.sun.messaging.jmq.jmsserver.util.*;
import com.sun.messaging.jmq.jmsserver.resources.*;
import com.sun.messaging.jmq.jmsserver.persist.Store;
import com.sun.messaging.jmq.jmsserver.persist.TransactionInfo;
import com.sun.messaging.jmq.jmsserver.Globals;
import com.sun.messaging.jmq.jmsserver.service.ConnectionUID;

import java.io.*;
import java.sql.*;
import java.util.*;

/**
* UpgradeStore contains static methods to upgrade old data to
* the latest version.
*/
public class UpgradeStore implements DBConstants {

    private BrokerResources br = Globals.getBrokerResources();
    private Logger logger = Globals.getLogger();
    private JDBCStore store;
    private DBManager dbMgr;
    private String brokerID;
    private long storeSessionID;
    private int oldStoreVersion;
    private String oldVersionTable;
    private String oldPropTable;
    private String oldConfigRecordTable;
    private String oldDestTable;
    private String oldMsgTable;
    private String oldStateTable;
    private String oldInterestTable;
    private String oldTxnTable;
    private String oldAckTable;
    private boolean useBlob;
   
    private static boolean DEBUG = false;
    static {
        if (Globals.getLogger().getLevel() <= Logger.DEBUG) DEBUG = true;
    }

    UpgradeStore(JDBCStore jdbcStore, int oldVersion) throws BrokerException {
        store = jdbcStore;
        dbMgr = DBManager.getDBManager();
        brokerID = dbMgr.getBrokerID();
        oldStoreVersion = oldVersion;

        if (oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400) {
            useBlob = true;
            oldVersionTable = dbMgr.getTableName(
                VersionDAO.TABLE + DBConstants.SCHEMA_VERSION_40);
            oldPropTable = dbMgr.getTableName(
                PropertyDAO.TABLE + DBConstants.SCHEMA_VERSION_40);
            oldConfigRecordTable = dbMgr.getTableName(
                ConfigRecordDAO.TABLE + DBConstants.SCHEMA_VERSION_40);
            oldDestTable = dbMgr.getTableName(
                DestinationDAO.TABLE + DBConstants.SCHEMA_VERSION_40);
            oldMsgTable = dbMgr.getTableName(
                MessageDAO.TABLE + DBConstants.SCHEMA_VERSION_40);
            oldStateTable = dbMgr.getTableName(
                ConsumerStateDAO.TABLE + DBConstants.SCHEMA_VERSION_40);
            oldInterestTable = dbMgr.getTableName(
                ConsumerDAO.TABLE + DBConstants.SCHEMA_VERSION_40);
            oldTxnTable = dbMgr.getTableName(
                TransactionDAO.TABLE + DBConstants.SCHEMA_VERSION_40);;
        } else if (oldStoreVersion == JDBCStore.OLD_STORE_VERSION_370) {
            useBlob = true;
            oldVersionTable = VERSION_TBL_37 + brokerID;
            oldPropTable = PROPERTY_TBL_37 + brokerID;
            oldConfigRecordTable = CONFIGRECORD_TBL_37 + brokerID;
            oldDestTable = DESTINATION_TBL_37 + brokerID;
            oldMsgTable = MESSAGE_TBL_37 + brokerID;
            oldStateTable = INTEREST_STATE_TBL_37 + brokerID;
            oldInterestTable = INTEREST_TBL_37 + brokerID;
            oldTxnTable = TXN_TBL_37 + brokerID;
            oldAckTable = TXNACK_TBL_37 + brokerID;
        } else {
            useBlob = false;
            oldVersionTable = VERSION_TBL_35 + brokerID;
            oldPropTable = PROPERTY_TBL_35 + brokerID;
            oldConfigRecordTable = CONFIGRECORD_TBL_35 + brokerID;
            oldDestTable = DESTINATION_TBL_35 + brokerID;
            oldMsgTable = MESSAGE_TBL_35 + brokerID;
            oldStateTable = INTEREST_STATE_TBL_35 + brokerID;
            oldInterestTable = INTEREST_TBL_35 + brokerID;
            oldTxnTable = TXN_TBL_35 + brokerID;
            oldAckTable = TXNACK_TBL_35 + brokerID;
        }
    }

    void upgradeStore(Connection conn)
  throws BrokerException {

  // log informational messages
  Object[] args = {(new Integer(JDBCStore.STORE_VERSION))};
  logger.logToAll(Logger.INFO,
            BrokerResources.I_UPGRADE_JDBCSTORE_IN_PROGRESS, args);

  if (store.resetMessage()) {
      // log message to remove old message
      logger.logToAll(Logger.INFO,
                BrokerResources.I_RESET_MESSAGES_IN_OLD_STORE);
      logger.logToAll(Logger.INFO,
                BrokerResources.I_UPGRADE_REMAINING_STORE_DATA);
  } else if (store.resetInterest()) {
      // log message to remove old interest
      logger.logToAll(Logger.INFO,
                BrokerResources.I_RESET_INTERESTS_IN_OLD_STORE);
      logger.logToAll(Logger.INFO,
                BrokerResources.I_UPGRADE_REMAINING_STORE_DATA);
  }

  try {
      // create the tables first
            DBTool.createTables( conn );

            // initialized the store session
            storeSessionID =
                dbMgr.getDAOFactory().getStoreSessionDAO().getStoreSession(
                    conn, brokerID );
  } catch (Throwable e) {
            String url = dbMgr.getCreateDBURL();
            if ( url == null || url.length() == 0 ) {
                url = dbMgr.getOpenDBURL();
            }
            String errorMsg = br.getKString(
                BrokerResources.E_CREATE_DATABASE_TABLE_FAILED, url);
            logger.logToAll(Logger.ERROR, errorMsg, e);
            throw new BrokerException(errorMsg, e);
  }

  try {
            conn.setAutoCommit(false);

            upgradeProperties(conn);
            upgradeChangeRecords(conn);
      upgradeDestinations(conn);
      upgradeMessages(conn);
      upgradeInterests(conn);
      upgradeTxns(conn);
            upgradeTxnAcks(conn);

      logger.logToAll(Logger.INFO, BrokerResources.I_UPGRADE_STORE_DONE);

            // Now we can drop the version table
      if (store.upgradeNoBackup()) {
                dropTable(conn, oldVersionTable);
      } else {
    // log message about the old store
    logger.logToAll(Logger.INFO, BrokerResources.I_REMOVE_OLD_JDBCSTORE);
      }
  } catch (Exception e) {
      // upgrade failed; log message
      logger.logToAll(Logger.ERROR, BrokerResources.I_REMOVE_NEW_JDBC_STORE);
      try {
    // remove everything and return
    DBTool.dropTables(conn, dbMgr.getTableNames(JDBCStore.STORE_VERSION));
      } catch (SQLException ex) {
    logger.logStack(Logger.ERROR,
                    BrokerResources.X_INTERNAL_EXCEPTION,
                    "Failed to clean up new tables after upgrade failed", ex);
            }

            if ( e instanceof BrokerException ) {
                throw (BrokerException)e;
            } else {
                throw new BrokerException( br.getKString(
                    BrokerResources.E_UPGRADE_STORE_FAILED), e );
            }
  }
    }

    /**
     * Upgrade destinations from version 350/370/400 table to current format (410)
     */
    private void upgradeDestinations(Connection conn) throws BrokerException {

        DestinationDAO dstDAO = dbMgr.getDAOFactory().getDestinationDAO();

  // SQL to select all destination from version 350/370 table
        StringBuffer strBuf = new StringBuffer(128);
        if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
            strBuf.append( "SELECT " )
                .append( DestinationDAO.DESTINATION_COLUMN ).append( ", " )
                .append( DestinationDAO.CONNECTION_ID_COLUMN ).append( ", " )
                .append( DestinationDAO.CONNECTED_TS_COLUMN ).append( ", " )
                .append( DestinationDAO.CREATED_TS_COLUMN );
        } else {
            strBuf.append( "SELECT " ).append( TDEST_CDEST );
        }
        strBuf.append( " FROM " ).append( oldDestTable );

        String getAllDestFromOldSQL = strBuf.toString();

        // SQL to insert a destination to new table
        String insertDestSQL = new StringBuffer(128)
            .append( "INSERT INTO " ).append( dstDAO.getTableName() )
            .append( " ( " )
            .append( DestinationDAO.ID_COLUMN ).append( ", " )
            .append( DestinationDAO.DESTINATION_COLUMN ).append( ", " )
            .append( DestinationDAO.IS_LOCAL_COLUMN ).append( ", " )
            .append( DestinationDAO.CONNECTION_ID_COLUMN ).append( ", " )
            .append( DestinationDAO.CONNECTED_TS_COLUMN ).append( ", " )
            .append( DestinationDAO.STORE_SESSION_ID_COLUMN ).append( ", " )
            .append( DestinationDAO.CREATED_TS_COLUMN )
            .append( ") VALUES ( ?, ?, ?, ?, ?, ?, ? )" )
            .toString();

        boolean dobatch = dbMgr.supportsBatchUpdates() && !dbMgr.isHADB();
  Statement stmt = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  Destination dst = null;
    Exception myex = null;
  try {
            pstmt = conn.prepareStatement( insertDestSQL );

            stmt = conn.createStatement();
      rs = stmt.executeQuery( getAllDestFromOldSQL );
      while (rs.next()) {
                Object obj = Util.readObject(rs, 1);
    dst = (Destination)obj;

                String destName = dst.getUniqueName();
                int isLocal = dst.getIsLocal() ? 1 : 0;
                long connectionID = -1;
                long connectedTS = -1;
                long createdTS = System.currentTimeMillis();

                if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
                    connectionID = rs.getLong(2);
                    connectedTS = rs.getLong(3);
                    createdTS = rs.getLong(4);
                } else if ( isLocal > 0 ) {
                    // Store additional info for temp destination
                    ConnectionUID cUID = dst.getConnectionUID();
                    if ( cUID != null ) {
                        connectionID = cUID.longValue();
                        connectedTS = createdTS;
                    }
                }

    // put destinations in new table
    try {
                    pstmt.setString( 1, destName );
                    Util.setObject( pstmt, 2, dst );
                    pstmt.setInt( 3, isLocal );
                    Util.setLong( pstmt, 4, connectionID );
                    Util.setLong( pstmt, 5, connectedTS );
                    Util.setLong( pstmt, 6, storeSessionID );
                    pstmt.setLong( 7, createdTS );

        if ( dobatch ) {
      pstmt.addBatch();
        } else {
      pstmt.executeUpdate();
        }
    } catch (IOException e) {
        IOException ex = DBManager.wrapIOException(
                        "[" + insertDestSQL + "]", e);
        throw ex;
    } catch (SQLException e) {
        SQLException ex = DBManager.wrapSQLException(
                        "[" + insertDestSQL + "]", e);
        throw ex;
    }
      }

      if ( dobatch ) {
    pstmt.executeBatch();
      }
      conn.commit();

      if (store.upgradeNoBackup()) {
    dropTable(conn, oldDestTable);
      }
  } catch (Exception e) {
        myex = e;
            String errorMsg = br.getKString(
                BrokerResources.X_JDBC_UPGRADE_DESTINATIONS_FAILED,
                (dst == null ? "loading" : dst.getUniqueName()));
      logger.logStack(Logger.ERROR, errorMsg, e);
      throw new BrokerException(errorMsg, e);
  } finally {
            Util.close( rs, stmt, null, myex );
            Util.close( null, pstmt, null, myex );
        }
    }

    /**
     * Upgrade messages and the associated interest list from
     * version 350/370/400 tables to current format (410)
     */
    private void upgradeMessages(Connection conn) throws BrokerException {

  String sql = null;
  int nummsg = 0;

  // first find out how many messages we have in the old table
  Statement stmt = null;
        ResultSet rs = null;
    Exception myex = null;
  try {
      sql = "SELECT COUNT(*) FROM " + oldMsgTable;
      stmt = conn.createStatement();
      rs = stmt.executeQuery(sql);
      if (rs.next()) {
    nummsg = rs.getInt(1);
      }
  } catch (SQLException e) {
        myex = e;
      logger.log(Logger.ERROR, BrokerResources.X_JDBC_QUERY_FAILED, sql, e);
      throw new BrokerException(
                br.getString(BrokerResources.X_JDBC_QUERY_FAILED, sql), e);
  } finally {
            Util.close( rs, stmt, null, myex );
        }

  if (Store.getDEBUG()) {
      logger.log(Logger.DEBUG,
                "number of messages in old table = " + nummsg);
  }

  boolean nobackup = store.upgradeNoBackup();
  if (nummsg == 0) {
      // no message in old table just return;
      if (nobackup) {
    // need to delete old tables
    dropTable(conn, oldMsgTable);
    dropTable(conn, oldStateTable);
      } // else do nothing
  } else if (store.resetMessage()) {
      if (nobackup) {
    // just delete old tables
    dropTable(conn, oldMsgTable);
    dropTable(conn, oldStateTable);
      } else {
    // reset old tables, i.e., delete all entries
    clearTable(conn, oldMsgTable);
    clearTable(conn, oldStateTable);
      }
  } else {
      // print info message
            logger.logToAll(Logger.INFO, br.getString(
                BrokerResources.I_UPGRADING_MESSAGES, String.valueOf(nummsg)));

      doUpgradeMsg(conn);

      if (nobackup) {
    dropTable(conn, oldMsgTable);
    dropTable(conn, oldStateTable);
      }
  }
    }

    private void doUpgradeMsg(Connection conn) throws BrokerException {

        MessageDAO msgDAO = dbMgr.getDAOFactory().getMessageDAO();

        HashMap oldIDToNewID = new HashMap();
        HashMap msgToDst = new HashMap();

  // SQL to select all messages from version 350/370 table
        StringBuffer strBuf = new StringBuffer(128);
        if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
            strBuf.append( "SELECT " )
                .append( MessageDAO.ID_COLUMN ).append( ", " )
                .append( MessageDAO.MESSAGE_COLUMN ).append( ", " )
                .append( MessageDAO.DESTINATION_ID_COLUMN ).append( ", " )
                .append( MessageDAO.CREATED_TS_COLUMN );
        } else {
            strBuf.append( "SELECT " )
                .append( TMSG_CMID ).append( ", " )
                .append( TMSG_CMSG ).append( ", " )
                .append( TMSG_CDID ).append( ", " )
                .append( 0 );
        }
        strBuf.append( " FROM " ).append( oldMsgTable );

        String getAllMsgFromOldSQL = strBuf.toString();

  Statement stmt = null;
  ResultSet rs = null;
  Packet msg = null;
        String oldMsgID = null;
    Exception myex = null;
  try {
      stmt = conn.createStatement();
      rs = stmt.executeQuery( getAllMsgFromOldSQL );
      while (rs.next()) {
                oldMsgID = rs.getString(1);

    msg = new Packet(false);
    msg.generateTimestamp(false);
    msg.generateSequenceNumber(false);
    InputStream is = useBlob ?
                    rs.getBlob(2).getBinaryStream() : rs.getBinaryStream(2);
    msg.readPacket(is);
    is.close();

                SysMessageID sysMsgID = msg.getSysMessageID();

                String dstID = rs.getString(3);
                long createdTS = createdTS = rs.getLong(4);

                if ( createdTS == 0 ) {
                    createdTS = sysMsgID.getTimestamp();
                }

                msgDAO.insert( conn, dstID, msg, null, null,
                    storeSessionID, createdTS, false );

                String newMsgID = sysMsgID.toString();
                oldIDToNewID.put(oldMsgID, newMsgID);
                msgToDst.put(newMsgID, dstID);
      }
  } catch (Exception e) {
        myex =e;
            String errorMsg = br.getKString(
                BrokerResources.X_JDBC_UPGRADE_MESSAGES_FAILED,
                (msg == null ? oldMsgID : msg.getSysMessageID().toString()));
      logger.logStack(Logger.ERROR, errorMsg, e);
      throw new BrokerException(errorMsg, e);
  } finally {
            Util.close( rs, stmt, null, myex );
        }

  // upgrade interest list
        ConsumerStateDAO stateDAO = dbMgr.getDAOFactory().getConsumerStateDAO();

  // SQL to select all interest states from version 350/370/400 table
        strBuf = new StringBuffer(128);
        if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
            strBuf.append( "SELECT " )
                .append( ConsumerStateDAO.MESSAGE_ID_COLUMN ).append( ", " )
                .append( ConsumerStateDAO.CONSUMER_ID_COLUMN ).append( ", " )
                .append( ConsumerStateDAO.STATE_COLUMN ).append( ", " )
                .append( ConsumerStateDAO.TRANSACTION_ID_COLUMN ).append( ", " )
                .append( ConsumerStateDAO.CREATED_TS_COLUMN );
        } else {
            strBuf.append( "SELECT " )
                .append( TINTSTATE_CMID ).append( ", " )
                .append( TINTSTATE_CCUID ).append( ", " )
                .append( TINTSTATE_CSTATE );
        }
        strBuf.append( " FROM " ).append( oldStateTable )
            .append( " WHERE " ).append( TINTSTATE_CSTATE ).append( " <> " )
            .append( Store.INTEREST_STATE_ACKNOWLEDGED );

        String getAllStateFromOldSQL = strBuf.toString();

        String insertStateSQL = new StringBuffer(128)
            .append( "INSERT INTO " ).append( stateDAO.getTableName() )
            .append( " ( " )
            .append( ConsumerStateDAO.MESSAGE_ID_COLUMN ).append( ", " )
            .append( ConsumerStateDAO.CONSUMER_ID_COLUMN ).append( ", " )
            .append( ConsumerStateDAO.STATE_COLUMN ).append( ", " )
            .append( ConsumerStateDAO.TRANSACTION_ID_COLUMN ).append( ", " )
            .append( ConsumerStateDAO.CREATED_TS_COLUMN )
            .append( ") VALUES ( ?, ?, ?, ?, ? )" )
            .toString();

        boolean dobatch = dbMgr.supportsBatchUpdates() && !dbMgr.isHADB();
        PreparedStatement pstmt = null;
  long cuid = 0;
        oldMsgID = null;
  try {
      pstmt = conn.prepareStatement(insertStateSQL);

            stmt = conn.createStatement();
      rs = stmt.executeQuery( getAllStateFromOldSQL );
      while (rs.next()) {
    oldMsgID = rs.getString(1);
    cuid = rs.getLong(2);
    int state = rs.getInt(3);

                String newMsgID = (String)oldIDToNewID.get(oldMsgID);
                if (newMsgID == null) {
                    String errorMsg = br.getKString(
                        BrokerResources.E_INTERNAL_BROKER_ERROR,
                        "Unable to update message ID format of interest " +
                        cuid + " for message " + oldMsgID);
                    throw new BrokerException(errorMsg);
                }

                String dst = (String)msgToDst.get(newMsgID);

    // ignore a state whose dst or message does not exists
    if (dst == null) {
                    logger.log(Logger.WARNING,
                        "Destination not found: ignore state of interest " +
                        cuid + " for message " + oldMsgID  );
                    continue;
    }

                long txnID = -1;
                long createdTS = System.currentTimeMillis();

                if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
                    txnID = rs.getLong(4);
                    if ( rs.wasNull() ) txnID = -1;
                    createdTS = rs.getLong(5);
                }

    try {
                    pstmt.setString( 1, newMsgID );
                    pstmt.setLong( 2, cuid );
                    pstmt.setInt( 3, state );
                    Util.setLong( pstmt, 4, txnID );
                    pstmt.setLong( 5, createdTS );

        if ( dobatch ) {
      pstmt.addBatch();
        } else {
      pstmt.executeUpdate();
        }
    } catch (SQLException e) {
        SQLException ex = DBManager.wrapSQLException(
                        "[" + insertStateSQL + "]", e);
        throw ex;
    }
      }

      msgToDst.clear();

      if ( dobatch ) {
    pstmt.executeBatch();
      }
            conn.commit();
  } catch (SQLException e) {
        myex = e;
            String errorMsg = br.getKString(
                BrokerResources.X_JDBC_UPGRADE_MESSAGES_FAILED,
                (oldMsgID == null ? "loading" : oldMsgID));
      logger.logStack(Logger.ERROR, errorMsg, e);
      throw new BrokerException(errorMsg, e);
  } finally {
            Util.close( rs, stmt, null, myex );
            Util.close( null, pstmt, null, myex );
        }
    }

    /**
     * Upgrade interests from version 350/370/400 table to current format (410)
     */
    private void upgradeInterests(Connection conn) throws BrokerException {

  String sql = "SELECT COUNT(*) FROM " + oldInterestTable;
  int numint = 0;

  // first find out how many interest we have in the old table
  Statement stmt = null;
        ResultSet rs = null;
    Exception myex = null;
  try {
      stmt = conn.createStatement();
      rs = stmt.executeQuery(sql);
      if (rs.next()) {
    numint = rs.getInt(1);
      }
  } catch (SQLException e) {
        myex = e;
      logger.log(Logger.ERROR, BrokerResources.X_JDBC_QUERY_FAILED, sql, e);
      throw new BrokerException(
                br.getString(BrokerResources.X_JDBC_QUERY_FAILED, sql), e);
  } finally {
            Util.close( rs, stmt, null, myex );
        }

  if (Store.getDEBUG()) {
      logger.log(Logger.DEBUG,
                "number of interests in old table = " + numint);
  }

  boolean nobackup = store.upgradeNoBackup();
  if (numint == 0) {
      // no interests in old table
      if (nobackup) {
    // need to drop old table
    dropTable(conn, oldInterestTable);
      } // else do nothing
  } else if (store.resetInterest()) {
      if (nobackup) {
    // just delete old table
    dropTable(conn, oldInterestTable);
      } else {
    // reset old table, i.e., delete all entries
    clearTable(conn, oldInterestTable);
      }
  } else {
      // upgrade
      doUpgradeInterests(store, conn);
  }
    }

    private void doUpgradeInterests(JDBCStore store, Connection conn)
  throws BrokerException {

        ConsumerDAO conDAO = dbMgr.getDAOFactory().getConsumerDAO();

  // SQL to select all interest from version 350/370/400 table
        StringBuffer strBuf = new StringBuffer(128);
        if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
            strBuf.append( "SELECT " )
                .append( ConsumerDAO.CONSUMER_COLUMN ).append( ", " )
                .append( ConsumerDAO.CREATED_TS_COLUMN );
        } else {
            strBuf.append( "SELECT " )
                .append( TINT_CINTEREST );
        }
        strBuf.append( " FROM " ).append( oldInterestTable );

        String getAllInterestFromOldSQL = strBuf.toString();

        // SQL to insert interest to new table
        String insertInterestSQL = new StringBuffer(128)
                .append( "INSERT INTO " ).append( conDAO.getTableName() )
                .append( " ( " )
                .append( ConsumerDAO.ID_COLUMN ).append( ", " )
                .append( ConsumerDAO.CONSUMER_COLUMN ).append( ", " )
                .append( ConsumerDAO.DURABLE_NAME_COLUMN ).append( ", " )
                .append( ConsumerDAO.CLIENT_ID_COLUMN ).append( ", " )
                .append( ConsumerDAO.CREATED_TS_COLUMN )
                .append( ") VALUES ( ?, ?, ?, ?, ? )" )
                .toString();

        boolean dobatch = dbMgr.supportsBatchUpdates() && !dbMgr.isHADB();
  PreparedStatement pstmt = null;
  Statement stmt = null;
  ResultSet rs = null;
  Consumer consumer = null;
    Exception myex = null;
  try {
            pstmt = conn.prepareStatement(insertInterestSQL);

            stmt = conn.createStatement();
      rs = stmt.executeQuery( getAllInterestFromOldSQL );
      while (rs.next()) {
    consumer = (Consumer)Util.readObject(rs, 1);

                String durableName = null;
                String clientID = null;
                if ( consumer instanceof Subscription ) {
                    Subscription sub = (Subscription)consumer;
                    durableName = sub.getDurableName();
                    clientID = sub.getClientID();
                }

                long createdTS = System.currentTimeMillis();
                if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
                    createdTS = rs.getLong(2);
                }

    // write to new table
    try {
                    pstmt.setLong( 1, consumer.getConsumerUID().longValue() );
                    Util.setObject( pstmt, 2, consumer );
                    Util.setString( pstmt, 3, durableName );
                    Util.setString( pstmt, 4, clientID );
                    pstmt.setLong( 5, createdTS );

        if ( dobatch ) {
      pstmt.addBatch();
        } else {
      pstmt.executeUpdate();
        }
    } catch (IOException e) {
        IOException ex = DBManager.wrapIOException(
                        "[" + insertInterestSQL + "]", e);
        throw ex;
    } catch (SQLException e) {
        SQLException ex = DBManager.wrapSQLException(
                        "[" + insertInterestSQL + "]", e);
        throw ex;
    }
      }

      if ( dobatch ) {
    pstmt.executeBatch();
      }
      conn.commit();

      if (store.upgradeNoBackup()) {
    // drop old table
    dropTable(conn, oldInterestTable);
      }
  } catch (Exception e) {
        myex = e;
            String errorMsg = br.getKString(
                BrokerResources.X_JDBC_UPGRADE_INTERESTS_FAILED,
                (consumer == null ? "loading" : consumer.toString()));
      logger.logStack(Logger.ERROR, errorMsg, e);
      throw new BrokerException(errorMsg, e);
  } finally {
            Util.close( rs, stmt, null, myex );
            Util.close( null, pstmt, null, myex );
        }
    }

    /**
     * Upgrade transactions from version 350/370/400 table to current format (410)
     */
    private void upgradeTxns(Connection conn) throws BrokerException {

        TransactionDAO txnDAO = dbMgr.getDAOFactory().getTransactionDAO();

  // SQL to select all transactions from version 350/370 table
        StringBuffer strBuf = new StringBuffer(128);
        if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
            strBuf.append( "SELECT " )
                .append( TransactionDAO.ID_COLUMN ).append( ", " )
                .append( TransactionDAO.STATE_COLUMN ).append( ", " )
                .append( TransactionDAO.TXN_STATE_COLUMN );
        } else {
            strBuf.append( "SELECT " )
                .append( TTXN_CTUID ).append( ", " )
                .append( TTXN_CSTATE ).append( ", " )
                .append( TTXN_CSTATEOBJ );
        }
        strBuf.append( " FROM " ).append( oldTxnTable )
            .append( " WHERE " ).append( TTXN_CSTATE ).append( " <> " )
            .append( DBConstants.TXN_DELETED );

        String getAllTxnsFromOldSQL = strBuf.toString();

        // SQL to insert transactions to new table
  String insertTxnSQL = new StringBuffer(128)
            .append( "INSERT INTO " ).append( txnDAO.getTableName() )
            .append( " ( " )
            .append( TransactionDAO.ID_COLUMN ).append( ", " )
            .append( TransactionDAO.TYPE_COLUMN ).append( ", " )
            .append( TransactionDAO.STATE_COLUMN ).append( ", " )
            .append( TransactionDAO.AUTO_ROLLBACK_COLUMN ).append( ", " )
            .append( TransactionDAO.XID_COLUMN ).append( ", " )
            .append( TransactionDAO.TXN_STATE_COLUMN ).append( ", " )
            .append( TransactionDAO.TXN_HOME_BROKER_COLUMN ).append( ", " )
            .append( TransactionDAO.TXN_BROKERS_COLUMN ).append( ", " )
            .append( TransactionDAO.STORE_SESSION_ID_COLUMN ).append( ", " )
            .append( TransactionDAO.EXPIRED_TS_COLUMN ).append( ", " )
            .append( TransactionDAO.ACCESSED_TS_COLUMN )
            .append( ") VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )" )
            .toString();

        boolean dobatch = dbMgr.supportsBatchUpdates() && !dbMgr.isHADB();
  PreparedStatement pstmt = null;
  Statement stmt = null;
  ResultSet rs = null;
  TransactionUID tid  = null;
    Exception myex = null;
  try {
      pstmt = conn.prepareStatement(insertTxnSQL);

            stmt = conn.createStatement();
      rs = stmt.executeQuery(getAllTxnsFromOldSQL);
      while (rs.next()) {
    long id = rs.getLong(1);
    tid = new TransactionUID(id);
    int state = rs.getInt(2);
   
    TransactionState txnState = (TransactionState)Util.readObject(rs, 3);
    if(DEBUG)
    {
      String msg = "reading transaction from old format: state="+state+
      " txnState = "+txnState;
      logger.log(Logger.DEBUG, msg);
    }
    txnState.setState(state);

    // insert in new table
    try {
                    pstmt.setLong( 1, id );
                    pstmt.setInt( 2, TransactionInfo.TXN_LOCAL );
                    pstmt.setInt( 3, state );
                    pstmt.setInt( 4, txnState.getType().intValue() );

                    JMQXid jmqXid = txnState.getXid();
                    if ( jmqXid != null ) {
                        pstmt.setString( 5, jmqXid.toString() );
                    } else {
                        pstmt.setNull( 5, Types.VARCHAR );
                    }

                    Util.setObject( pstmt, 6, txnState );
                    Util.setObject( pstmt, 7, null );
                    Util.setObject( pstmt, 8, null );                   

                    pstmt.setLong( 9, storeSessionID );
                    pstmt.setLong( 10, txnState.getExpirationTime() );
                    pstmt.setLong( 11, txnState.getLastAccessTime() );

        if (dobatch) {
      pstmt.addBatch();
        } else {
      pstmt.executeUpdate();
        }
    } catch (IOException e) {
        IOException ex = DBManager.wrapIOException(
                        "[" + insertTxnSQL + "]", e);
        throw ex;
    } catch (SQLException e) {
        SQLException ex = DBManager.wrapSQLException(
                        "[" + insertTxnSQL + "]", e);
        throw ex;
    }
      }

      if (dobatch) {
    pstmt.executeBatch();
      }
      conn.commit();

            // Only delete txn table after we upgrade txn ack!!!
  } catch (Exception e) {
        myex = e;
            String errorMsg = br.getKString(
                BrokerResources.X_JDBC_UPGRADE_TRANSACTIONS_FAILED,
                (tid == null ? "loading" : tid.toString()));
      logger.logStack(Logger.ERROR, errorMsg, e);
      throw new BrokerException(errorMsg, e);
  } finally {
            Util.close( rs, stmt, null, myex );
            Util.close( null, pstmt, null, myex );
        }
    }

    /**
     * Upgrade transaction acknowledgements from version 350/370 table
     * to current format (410)
     */
    private void upgradeTxnAcks(Connection conn) throws BrokerException {

        if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
            // In 400, ack table has been folded into consumer state table
            return;
        }

        ConsumerStateDAO stateDAO = dbMgr.getDAOFactory().getConsumerStateDAO();

  // SQL to select all acknowledgements from version 350/370 table
  String getAllTxnAcksFromOldSQL =
            "SELECT atbl." + TTXNACK_CTUID + ", " + TTXNACK_CACK +
            " FROM " + oldTxnTable + " ttbl, " + oldAckTable + " atbl" +
            " WHERE ttbl." + TTXN_CTUID + " = atbl." + TTXNACK_CTUID;

        // SQL to insert acknowledgements to consumer state table;
        // for 400, txn ack is represent as a column in consumer state table.
        String insertTxnAckSQL = new StringBuffer(128)
            .append( "UPDATE " ).append( stateDAO.getTableName() )
            .append( " SET " )
            .append( ConsumerStateDAO.TRANSACTION_ID_COLUMN ).append( " = ? " )
            .append( " WHERE " )
            .append( ConsumerStateDAO.MESSAGE_ID_COLUMN ).append( " = ?" )
            .append( " AND " )
            .append( ConsumerStateDAO.CONSUMER_ID_COLUMN ).append( " = ?" )
            .toString();

        boolean dobatch = dbMgr.supportsBatchUpdates() && !dbMgr.isHADB();
  PreparedStatement pstmt = null;
  Statement stmt = null;
  ResultSet rs = null;
  TransactionUID tid  = null;
    Exception myex = null;
  try {
      pstmt = conn.prepareStatement(insertTxnAckSQL);

            stmt = conn.createStatement();
      rs = stmt.executeQuery(getAllTxnAcksFromOldSQL);
      while (rs.next()) {
    long id = rs.getLong(1);
    tid = new TransactionUID(id);
    TransactionAcknowledgement ack =
                    (TransactionAcknowledgement)Util.readObject(rs, 2);

    // insert in new table
    try {
                    pstmt.setLong( 1, id );
                    pstmt.setString( 2, ack.getSysMessageID().toString() );
                    pstmt.setLong( 3, ack.getStoredConsumerUID().longValue() );

        if (dobatch) {
      pstmt.addBatch();
        } else {
      pstmt.executeUpdate();
        }
    } catch (SQLException e) {
        SQLException ex = DBManager.wrapSQLException(
                        "[" + insertTxnAckSQL + "]", e);
        throw ex;
    }
      }

      if (dobatch) {
    pstmt.executeBatch();
      }
      conn.commit();

      if (store.upgradeNoBackup()) {
                dropTable(conn, oldTxnTable);
                dropTable(conn, oldAckTable);
      }
  } catch (Exception e) {
        myex = e;
            String errorMsg = br.getKString(
                BrokerResources.X_JDBC_UPGRADE_TXNACK_FAILED,
                (tid == null ? "loading" : tid.toString() ) );
      logger.logStack(Logger.ERROR, errorMsg, e);
      throw new BrokerException(errorMsg, e);
  } finally {
            Util.close( rs, stmt, null, myex );
            Util.close( null, pstmt, null, myex );
        }
    }

    /**
     * Upgrade configuration records from version 350/370/400 table to
     * current format (410)
     */
    private void upgradeChangeRecords(Connection conn) throws BrokerException {

        ConfigRecordDAO recordDAO = dbMgr.getDAOFactory().getConfigRecordDAO();

  // SQL to select all ConfigRecord from version 350/370/400 table
  StringBuffer strBuf = new StringBuffer(128)
            .append( "SELECT " ).append( TCONFIG_CRECORD ).append( ", " );
        if ( oldStoreVersion == JDBCStore.OLD_STORE_VERSION_400 ) {
            strBuf.append( ConfigRecordDAO.CREATED_TS_COLUMN );
        } else {
            strBuf.append( TCONFIG_CTIME );
        }
        strBuf.append( " FROM " ).append( oldConfigRecordTable );

        String getAllRecordFromOldSQL = strBuf.toString();

        // SQL to insert ConfigRecord to new table
        String insertRecordSQL = new StringBuffer(128)
            .append( "INSERT INTO " ).append( recordDAO.getTableName() )
            .append( " ( " )
            .append( ConfigRecordDAO.RECORD_COLUMN ).append( ", " )
            .append( ConfigRecordDAO.CREATED_TS_COLUMN )
            .append( ") VALUES ( ?, ? )" )
            .toString();

  PreparedStatement pstmt = null;
  Statement stmt = null;
  ResultSet rs = null;
  Long recordTS = null;
    Exception myex = null;
  try {
            pstmt = conn.prepareStatement( insertRecordSQL );

      stmt = conn.createStatement();
      rs = stmt.executeQuery( getAllRecordFromOldSQL );
      while (rs.next()) {
    byte[] rec  = Util.readBytes(rs, 1);
                long ts = rs.getLong(2);
    recordTS = new Long( ts );

    // insert in new table
    try {
                    Util.setBytes( pstmt, 1, rec );
                    pstmt.setLong( 2, ts );

                    pstmt.executeUpdate();
    } catch (IOException e) {
        IOException ex = DBManager.wrapIOException(
                        "[" + insertRecordSQL + "]", e);
        throw ex;
    } catch (SQLException e) {
        SQLException ex = DBManager.wrapSQLException(
                        "[" + insertRecordSQL + "]", e);
        throw ex;
    }
      }

      conn.commit();

      if (store.upgradeNoBackup()) {
    dropTable(conn, oldConfigRecordTable);
      }
  } catch (Exception e) {
        myex = e;
            String errorMsg = br.getKString(
                BrokerResources.X_JDBC_UPGRADE_CRECORDS_FAILED,
                (recordTS == null ? "loading" : recordTS.toString()));
      logger.logStack(Logger.ERROR, errorMsg, e);
      throw new BrokerException(errorMsg, e);
  } finally {
            Util.close( rs, stmt, null, myex );
            Util.close( null, pstmt, null, myex );
        }
    }

    /**
     * Upgrade properties from version 350/370/400 table to current format (410)
     */
    private void upgradeProperties(Connection conn) throws BrokerException {

        PropertyDAO propDAO = dbMgr.getDAOFactory().getPropertyDAO();

  // SQL to select all property from version 350/370/400 table
  String getAllPropFromOldSQL =
            "SELECT " + TPROP_CNAME + ", " + TPROP_CVALUE + " FROM " + oldPropTable;

        // SQL to insert property to new table
        String insertPropSQL = new StringBuffer(128)
            .append( "INSERT INTO " ).append( propDAO.getTableName() )
            .append( " ( " )
            .append( PropertyDAO.PROPNAME_COLUMN ).append( ", " )
            .append( PropertyDAO.PROPVALUE_COLUMN )
            .append( ") VALUES ( ?, ? )" )
            .toString();

        boolean dobatch = dbMgr.supportsBatchUpdates();
  Statement stmt = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  String name = null;
    Exception myex = null;
  try {
            pstmt = conn.prepareStatement( insertPropSQL );

      stmt = conn.createStatement();
      rs = stmt.executeQuery( getAllPropFromOldSQL );
      while (rs.next()) {
    name = rs.getString(1);
    Object value = Util.readObject(rs, 2);

    // insert in new table
    try {
                    pstmt.setString( 1, name );
                    Util.setObject( pstmt, 2, value );

        if ( dobatch ) {
      pstmt.addBatch();
        } else {
      pstmt.executeUpdate();
        }
    } catch (IOException e) {
        IOException ex = DBManager.wrapIOException(
                        "[" + insertPropSQL + "]", e);
        throw ex;
    } catch (SQLException e) {
        SQLException ex = DBManager.wrapSQLException(
                        "[" + insertPropSQL + "]", e);
        throw ex;
    }
      }

      if ( dobatch ) {
    pstmt.executeBatch();
      }
      conn.commit();

      if (store.upgradeNoBackup()) {
    dropTable(conn, oldPropTable);
      }
  } catch (Exception e) {
        myex = e;
            String errorMsg = br.getKString(
                BrokerResources.X_JDBC_UPGRADE_PROPERTIES_FAILED,
                (name == null ? "loading" : name));
      logger.logStack(Logger.ERROR, errorMsg, e);
      throw new BrokerException(errorMsg, e);
        } finally {
            Util.close( rs, stmt, null, myex );
            Util.close( null, pstmt, null, myex );
        }
    }

    private void dropTable(Connection conn, String table)
        throws BrokerException {

  String sql = "DROP TABLE " + table;

        Statement stmt = null;
    Exception myex = null;
  try {
      stmt = conn.createStatement();
      stmt.executeUpdate(sql);
      conn.commit();

      if (Store.getDEBUG()) {
    Globals.getLogger().log(Logger.DEBUG, "Dropped table " + table);
      }
  } catch (SQLException e) {
        myex = e;
      Globals.getLogger().log(Logger.ERROR,
                BrokerResources.I_DROP_TABLE_FAILED, table,
                DBManager.wrapSQLException("[" + sql + "]", e));
  } finally {
            Util.close( null, stmt, null, myex );
        }
    }

    private void clearTable(Connection conn, String table)
  throws BrokerException {

  String sql = "DELETE FROM " + table;

        Statement stmt = null;
    Exception myex = null;
  try {
      stmt = conn.createStatement();
      int numdeleted = stmt.executeUpdate(sql);
      conn.commit();

      if (Store.getDEBUG()) {
    Globals.getLogger().log(Logger.DEBUG, "Deleted " + numdeleted +
                    " entries in " + table);
      }
  } catch (SQLException e) {
        myex = e;
            SQLException ex = DBManager.wrapSQLException("[" + sql + "]", e);
            String errorMsg = Globals.getBrokerResources().getString(
                    BrokerResources.X_JDBC_CLEAR_TABLE_FAILED, table);
      Globals.getLogger().log(Logger.ERROR, errorMsg, ex);
      throw new BrokerException(errorMsg, ex);
  } finally {
            Util.close( null, stmt, null, myex );
        }
    }
}

TOP

Related Classes of com.sun.messaging.jmq.jmsserver.persist.jdbc.UpgradeStore

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.