Package org.xmlBlaster.contrib.replication

Source Code of org.xmlBlaster.contrib.replication.ReplSourceEngine

package org.xmlBlaster.contrib.replication;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.TextMessage;

import org.xmlBlaster.contrib.I_ChangePublisher;
import org.xmlBlaster.contrib.I_Info;
import org.xmlBlaster.contrib.I_Update;
import org.xmlBlaster.contrib.dbwriter.info.SqlDescription;
import org.xmlBlaster.contrib.dbwriter.info.SqlInfo;
import org.xmlBlaster.contrib.replication.impl.ReplManagerPlugin;
import org.xmlBlaster.contrib.replication.impl.SpecificDefault;
import org.xmlBlaster.jms.XBDestination;
import org.xmlBlaster.jms.XBMessageProducer;
import org.xmlBlaster.jms.XBSession;
import org.xmlBlaster.util.I_ReplaceContent;
import org.xmlBlaster.util.Timestamp;
import org.xmlBlaster.util.def.Constants;
import org.xmlBlaster.util.def.PriorityEnum;
import org.xmlBlaster.util.qos.ClientProperty;
import org.xmlBlaster.util.qos.MsgQosData;

public class ReplSourceEngine implements I_Update, ReplicationConstants, I_ReplaceContent {
  
   private final static Logger log = Logger.getLogger(ReplSourceEngine.class.getName());
  
   private String replPrefix;
   private I_ChangePublisher publisher;
   private I_ReplSource source;
   private long messageSeq;
  
   public ReplSourceEngine(String replPrefix, I_ChangePublisher publisher, I_ReplSource source) {
      this.replPrefix = replPrefix;
      this.publisher = publisher;
      this.source = source;
   }
  
   /**
    * @see org.xmlBlaster.contrib.I_Update#update(java.lang.String, byte[], java.util.Map)
    */
   public final void update(String topic, InputStream is, Map attrMap) {

      String msg = new String();
      try {
         if (is != null)
            msg = new String(ReplManagerPlugin.getContent(is));
         // this comes from the requesting ReplSlave
         log.info("update for '" + topic + "' and msg='" + msg + "'");
         if (REPL_REQUEST_UPDATE.equals(msg)) {
            ClientProperty prop = (ClientProperty)attrMap.get("_sender");
            if (prop == null)
               throw new Exception("update for '" + msg + "' failed since no '_sender' specified");
            String replManagerAddress = prop.getStringValue();

            String replTopic = source.getTopic();
            if (replTopic == null)
               throw new Exception("update for '" + msg + "' failed since the property 'mom.topicName' has not been defined. Check your DbWatcher Configuration file");

            prop = (ClientProperty)attrMap.get(SLAVE_NAME);
            if (prop == null)
               throw new Exception("update for '" + msg + "' failed since no '_slaveName' specified");
            String slaveName = prop.getStringValue();
           
            prop = (ClientProperty)attrMap.get(REPL_VERSION);
            String requestedVersion = null;
            if (prop != null)
               requestedVersion = prop.getStringValue();
            // this.dbSpecific.initiateUpdate(replTopic, destination, slaveName);
            prop = (ClientProperty)attrMap.get(INITIAL_FILES_LOCATION);
            String initialFilesLocation = null;
            if (prop != null)
               initialFilesLocation = prop.getStringValue();
           
            prop = (ClientProperty)attrMap.get(INITIAL_UPDATE_ONLY_REGISTER);
            boolean onlyRegister = false;
            if (prop != null)
               onlyRegister = prop.getBooleanValue();
           
            // String slaveName, String replVersion, String initialFilesLocation, boolean onlyRegister
            source.initialUpdate(replTopic, replManagerAddress, slaveName, requestedVersion, initialFilesLocation, onlyRegister);
           
         }
         else if (REPL_REQUEST_CANCEL_UPDATE.equals(msg)) {
            // do cancel
            ClientProperty prop = (ClientProperty)attrMap.get(SLAVE_NAME);
            if (prop == null)
               throw new Exception("update for '" + msg + "' failed since no '_slaveName' specified");
            String slaveName = prop.getStringValue();
            source.cancelUpdate(slaveName);
         }
         else if (REPL_REQUEST_RECREATE_TRIGGERS.equals(msg)) {
            source.recreateTriggers();
         }
         else if (STATEMENT_ACTION.equals(msg)) {
            String sql = ((ClientProperty)attrMap.get(STATEMENT_ATTR)).getStringValue();
            boolean isHighPrio = ((ClientProperty)attrMap.get(STATEMENT_PRIO_ATTR)).getBooleanValue();
            long maxResponseEntries = ((ClientProperty)attrMap.get(MAX_ENTRIES_ATTR)).getLongValue();
            String statementId = ((ClientProperty)attrMap.get(STATEMENT_ID_ATTR)).getStringValue();
            String sqlTopic =  ((ClientProperty)attrMap.get(SQL_TOPIC_ATTR)).getStringValue();
            log.info("Be aware that the number of entries in the result set will be limited to '" + maxResponseEntries + "'. To change this use 'replication.sqlMaxEntries'");
            final boolean isMaster = true;
            byte[] response  = null;
            Exception ex = null;
            try {
               response = source.executeStatement(sql, maxResponseEntries, isHighPrio, isMaster, sqlTopic, statementId);
            }
            catch (Exception e) {
               response = "".getBytes();
               ex = e;
            }
           
            if (this.publisher != null) {
               Map map = new HashMap();
               map.put(MASTER_ATTR, this.replPrefix);
               map.put(STATEMENT_ID_ATTR, statementId);
               map.put("_command", STATEMENT_ACTION);
               if (ex != null)
                  map.put(EXCEPTION_ATTR, ex.getMessage());
               this.publisher.publish(sqlTopic, response, map);
            }
            if (ex != null)
               throw ex;
         }
         else if (INITIAL_UPDATE_START_BATCH.equals(msg)) {
            source.startInitialUpdateBatch();
         }
         else if (INITIAL_UPDATE_COLLECT.equals(msg)) {
            source.collectInitialUpdate();
         }
         else {
            log.warning("update from '" + topic + "' with request '" + msg + "'");
         }
      }
      catch (Throwable ex) {
         log.severe("An exception occured when processing the received update '" + msg + "': " + ex.getMessage());
         ex.printStackTrace();
      }
   }
  
  
   /**
    * Sending this message will reactivate the Dispatcher of the associated slave
    * @param topic
    * @param filename
    * @param replManagerAddress
    * @param slaveName
    * @param minKey
    * @param maxKey
    * @throws Exception
    */
   public final void sendInitialDataResponse(String[] slaveSessionNames, String replManagerAddress, long minKey, long maxKey) throws Exception {
      HashMap attrs = new HashMap();
      attrs.put("_destination", replManagerAddress);
      attrs.put("_command", "INITIAL_DATA_RESPONSE");
      attrs.put("_minReplKey", "" + minKey);
      attrs.put("_maxReplKey", "" + maxKey);
      attrs.put(SLAVE_NAME, SpecificDefault.toString(slaveSessionNames));
      if (publisher != null)
         publisher.publish("", "INITIAL_DATA_RESPONSE".getBytes(), attrs);
      else
         log.warning("request for sending initial response can not be done since no publisher configured");
   }

   /**
    * Sending this message will reactivate the Dispatcher of the associated slave
    * @param topic
    * @param filename
    * @param replManagerAddress
    * @param slaveName
    * @param minKey
    * @param maxKey
    * @throws Exception
    */
   public static void sendInitReplMsg(I_ChangePublisher publisher,
                                        String[] slaveSessionNames,
                                        String prefixWithVersion,
                                        String cascadeSlaveSessionName,
                                        String cascadeReplicationPrefix,
                                        String realInitialFilesLocation,
                                        boolean force) throws Exception {
      HashMap attrs = new HashMap();
      attrs.put("_destination", ReplManagerPlugin.SESSION_ID);
      attrs.put("_command", "INITIATE_REPLICATION");
      StringBuffer buf = new StringBuffer();
      for (int i=0; i < slaveSessionNames.length; i++) {
         if (i != 0)
            buf.append(",");
         buf.append(slaveSessionNames[i]);
      }
      attrs.put("_slaveSessionName", buf.toString());
      attrs.put("_prefixWithVersion", prefixWithVersion);
      attrs.put("_cascadeSlaveSessionName", cascadeSlaveSessionName);
      attrs.put("_cascadeReplicationPrefix", cascadeReplicationPrefix);
      attrs.put("_realInitialFilesLocation", realInitialFilesLocation);
      if (force)
         attrs.put("_force", "true");
      if (publisher != null)
         publisher.publish("", "INITIAL_DATA_RESPONSE".getBytes(), attrs);
      else
         log.warning("request for sending initial response can not be done since no publisher configured");
   }

   public void sendEndOfTransitionMessage(I_Info info, String initialDataTopic, String[] slaveSessionNames) throws JMSException {
      XBSession session = this.publisher.getJmsSession();
      XBDestination dest = new XBDestination(initialDataTopic, SpecificDefault.toString(slaveSessionNames));
      XBMessageProducer producer = new XBMessageProducer(session, dest);
      producer.setPriority(PriorityEnum.HIGH_PRIORITY.getInt());
      producer.setDeliveryMode(DeliveryMode.PERSISTENT);
      String dumpId = "" + new Timestamp().getTimestamp();
      sendEndOfTransitionMessage(info, session, null, null, dumpId, producer);
   }
  
   public void sendEndOfTransitionMessage(I_Info info, XBSession session, String initialFilesLocation, String shortFilename, String dumpId, XBMessageProducer producer) throws JMSException {
      TextMessage  endMsg = session.createTextMessage();
      SqlInfo sqlInfo = new SqlInfo(info);
      SqlDescription description = new SqlDescription(info);

      description.setAttribute(END_OF_TRANSITION , "" + true);
      endMsg.setBooleanProperty(END_OF_TRANSITION , true);
      description.setAttribute(FILENAME_ATTR, shortFilename);
      endMsg.setStringProperty(FILENAME_ATTR, shortFilename);
      if (initialFilesLocation != null) {
         description.setAttribute(INITIAL_FILES_LOCATION, initialFilesLocation);
         endMsg.setStringProperty(INITIAL_FILES_LOCATION, initialFilesLocation);
         description.setAttribute(INITIAL_DATA_ID, dumpId);
         endMsg.setStringProperty(INITIAL_DATA_ID, dumpId);
      }
      sqlInfo.setDescription(description);
      endMsg.setText(sqlInfo.toXml(""));
      producer.send(endMsg);
   }
  
   public MsgQosData preparePubQos(MsgQosData qosData) {
      if (qosData == null)
         return qosData;
      if (qosData.getDestinations() != null && qosData.getDestinations().size() > 0) {
         qosData.addClientProperty(NUM_OF_TRANSACTIONS, -1L);
         return qosData;
      }
      prepareQosMap(qosData.getClientProperties());
      return qosData;
   }
  
   private void prepareQosMap(Map props) {
      messageSeq++;
      ClientProperty prop = new ClientProperty(MESSAGE_SEQ, Constants.TYPE_LONG, null, "" + messageSeq);
      props.put(MESSAGE_SEQ, prop);
      prop = new ClientProperty(REPL_KEY_ATTR, Constants.TYPE_LONG, null, "" + messageSeq);
      props.put(REPL_KEY_ATTR, prop);
      prop = new ClientProperty(TRANSACTION_SEQ, Constants.TYPE_LONG, null, "" + messageSeq);
      props.put(TRANSACTION_SEQ, prop);
      prop = new ClientProperty(ABSOLUTE_COUNT, Constants.TYPE_BOOLEAN, null, "true");
      props.put(ABSOLUTE_COUNT, prop);
   }
  
   public byte[] replace(byte[] oldContent, Map clientProperties) {
      prepareQosMap(clientProperties);
      return oldContent;
   }

  
}
TOP

Related Classes of org.xmlBlaster.contrib.replication.ReplSourceEngine

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.