FaultInjection.java :  » JMS » Open-Message-Queue » com » sun » messaging » jmq » jmsserver » Java Open Source

Java Open Source » JMS » Open Message Queue 
Open Message Queue » com » sun » messaging » jmq » jmsserver » FaultInjection.java
/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (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/CDDLv1.0.html.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * HEADER in each file and include the License file at
 * https://glassfish.dev.java.net/public/CDDLv1.0.html.  
 *
 * If applicable add the following below this CDDL HEADER,
 * with the fields enclosed by brackets "[]" replaced with 
 * your own identifying information: Portions Copyright 
 * [year] [name of copyright owner]
 */

/*
 * @(#)FaultInjection.java  1.11 05/02/06
 *
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 */ 

package com.sun.messaging.jmq.jmsserver;

import java.util.*;
import com.sun.messaging.jmq.util.selector.*;
import com.sun.messaging.jmq.util.log.*;
import java.io.*;
import com.sun.messaging.jmq.jmsserver.util.BrokerException;
import com.sun.messaging.jmq.jmsserver.Globals;

/**
 * All fault target constants start with FAULT_ and
 * only fault target constant starts with FAULT_
 *
 */
public class FaultInjection 
{
     static FaultInjection fault = null;

     Logger logger = Globals.getLogger();

     Set injections = null;
     Map injectionSelectors = null;
     Map injectionProps = null;
     public static boolean FAULT_INJECTION = false;

     /**
      * 1 is before processing
      * 2 is after processing, before reply
      * 3 is after reply
      */
     public static String STAGE_1 = "1";
     public static String STAGE_2 = "2";
     public static String STAGE_3 = "3";

     public static String FAULT_TXN_START_1 = "txn.start.1";
     public static String FAULT_TXN_END_1 = "txn.end.1";
     public static String FAULT_TXN_PREPARE_1 = "txn.prepare.1";
     public static String FAULT_TXN_COMMIT_1 = "txn.commit.1";
     public static String FAULT_TXN_ROLLBACK_1 = "txn.rollback.1";

     public static String FAULT_TXN_START_2 = "txn.start.2";
     public static String FAULT_TXN_END_2 = "txn.end.2";
     public static String FAULT_TXN_PREPARE_2 = "txn.prepare.2";
     public static String FAULT_TXN_COMMIT_2 = "txn.commit.2";
     public static String FAULT_TXN_ROLLBACK_2 = "txn.rollback.2";

     public static String FAULT_TXN_START_3 = "txn.start.3";
     public static String FAULT_TXN_END_3 = "txn.end.3";
     public static String FAULT_TXN_PREPARE_3 = "txn.prepare.3";
     public static String FAULT_TXN_COMMIT_3 = "txn.commit.3";
     public static String FAULT_TXN_ROLLBACK_3 = "txn.rollback.3";

     // after db update but before reply
     public static String FAULT_TXN_COMMIT_4 = "txn.commit.4";
     public static String FAULT_TXN_ROLLBACK_4 = "txn.rollback.4";

     // additional properties supported on acks
     //     mqAckCount - number of acks received
     //     mqIsTransacted - is in transaction
     public static String MSG_ACKCOUNT_PROP = "mqAckCount";

     public static String FAULT_ACK_MSG_1 = "msg.ack.1";
     public static String FAULT_ACK_MSG_2 = "msg.ack.2";
     public static String FAULT_ACK_MSG_3 = "msg.ack.3";


     // on messages all message properties are set plut
     //      mqMsgCount - mumber of messages received
     //      MQIsTransacted - is in transaction
     public static String FAULT_SEND_MSG_1 = "msg.send.1";
     public static String FAULT_SEND_MSG_2 = "msg.send.2";
     public static String FAULT_SEND_MSG_3 = "msg.send.3";

     /******************************************************************** 
      *REMOTE ACK - Protocol 
      *
      *    Support followoing properties
      *    mqAckCount:
      *      consumer broker -
      *        on sending the ?th remote ack of ackType to any remote broker 
      *      message home broker -
      *        on receiving the ?th remote ack of ackType from any remote broker 
      *
      *  Fault ID syntax: msg.remote_ack.<home>.<layer>.<ackType>.<n>
      *
      *  where <home> "home" if fault occurs on msg home broker else ""
      *        <layer> "p" for protocol, "c" for core
      *        <ackType> "" non-txn'ed or 3.5/3.6 cluster protocol  
      *                  "txnack", "txnprepare", "txnrollback", "txncommit" 
      *        <n> meaning for protocol layer ("p")
      *            "1" before send (in buffer) or unpon receive (home) protocol
      *            "2" before receive reply or send (home) reply 
      *            "3" after receive reply or send (home, in buffer) reply
      *
      ********************************************************************/
     public static String MSG_REMOTE_ACK_TXNACK      = "txnack.";
     public static String MSG_REMOTE_ACK_TXNPREPARE  = "txnprepare.";
     public static String MSG_REMOTE_ACK_TXNROLLBACK = "txnrollback.";
     public static String MSG_REMOTE_ACK_TXNCOMMIT   = "txncommit.";
     public static String MSG_REMOTE_ACK_P      = "msg.remote_ack.p.";
     public static String MSG_REMOTE_ACK_HOME_P = "msg.remote_ack.home.p.";

     public static String FAULT_MSG_REMOTE_ACK_P_TXNACK_1 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNACK+"1";
     public static String FAULT_MSG_REMOTE_ACK_P_TXNACK_2 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNACK+"2";
     public static String FAULT_MSG_REMOTE_ACK_P_TXNACK_3 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNACK+"3";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNACK_1 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNACK+"1";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNACK_2 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNACK+"2";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNACK_3 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNACK+"3";

     public static String FAULT_MSG_REMOTE_ACK_P_TXNPREPARE_1 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNPREPARE+"1";
     public static String FAULT_MSG_REMOTE_ACK_P_TXNPREPARE_2 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNPREPARE+"2";
     public static String FAULT_MSG_REMOTE_ACK_P_TXNPREPARE_3 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNPREPARE+"3";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNPREPARE_1 =
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNPREPARE+"1";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNPREPARE_2 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNPREPARE+"2";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNPREPARE_3 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNPREPARE+"3";

     public static String FAULT_MSG_REMOTE_ACK_P_TXNROLLBACK_1 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNROLLBACK+"1";
     public static String FAULT_MSG_REMOTE_ACK_P_TXNROLLBACK_2 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNROLLBACK+"2";
     public static String FAULT_MSG_REMOTE_ACK_P_TXNROLLBACK_3 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNROLLBACK+"3";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNROLLBACK_1 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNROLLBACK+"1";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNROLLBACK_2 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNROLLBACK+"2";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNROLLBACK_3 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNROLLBACK+"3";

     public static String FAULT_MSG_REMOTE_ACK_P_TXNCOMMIT_P_1 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNCOMMIT+"1";
     public static String FAULT_MSG_REMOTE_ACK_P_TXNCOMMIT_P_2 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNCOMMIT+"2";
     public static String FAULT_MSG_REMOTE_ACK_P_TXNCOMMIT_P_3 = 
                            MSG_REMOTE_ACK_P+MSG_REMOTE_ACK_TXNCOMMIT+"3";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNCOMMIT_1 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNCOMMIT+"1";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNCOMMIT_2 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNCOMMIT+"2";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_TXNCOMMIT_3 = 
                            MSG_REMOTE_ACK_HOME_P+MSG_REMOTE_ACK_TXNCOMMIT+"3";

     public static String FAULT_MSG_REMOTE_ACK_P_1 = MSG_REMOTE_ACK_P+"1";
     public static String FAULT_MSG_REMOTE_ACK_P_2 = MSG_REMOTE_ACK_P+"2";
     public static String FAULT_MSG_REMOTE_ACK_P_3 = MSG_REMOTE_ACK_P+"3";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_1 = MSG_REMOTE_ACK_HOME_P+"1";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_2 = MSG_REMOTE_ACK_HOME_P+"2";
     public static String FAULT_MSG_REMOTE_ACK_HOME_P_3 = MSG_REMOTE_ACK_HOME_P+"3";


     public static FaultInjection getInjection()
     {
         if (fault == null)
             fault = new FaultInjection();

         return fault;
     }
     public FaultInjection() {
         injections = Collections.synchronizedSet(new HashSet());
         injectionSelectors = Collections.synchronizedMap(new HashMap());
         injectionProps = Collections.synchronizedMap(new HashMap());
     }

     public void setFault(String fault, String selector)
         throws SelectorFormatException
     {
         setFault(fault, selector, null);
     }

     public void setFault(String fault, String selector, Map props)
         throws SelectorFormatException
     {
         logger.log(Logger.INFO,"Setting Fault " + fault +
            "[ selector=" + selector + "]");
         injections.add(fault);
         if (selector != null && selector.length() != 0) {
            // create a selector and insert
            Selector s = Selector.compile(selector);
            injectionSelectors.put(fault, s);
         }
         if (props != null)
            injectionProps.put(fault, props);

     }

     public void unsetFault(String fault) {
         logger.log(Logger.INFO,"Removing Fault " + fault );
         injections.remove(fault);
         injectionSelectors.remove(fault);
         injectionProps.remove(fault);
     }

     class FaultInjectionException extends Exception
     {
         public String toString() {
             return "FaultInjectionTrace";
         }
     }

     public void setFaultInjection(boolean inject)
     {
         if (FAULT_INJECTION != inject) {
            if (inject) {
                logger.log(Logger.INFO,"Turning on Fault Injection");
            } else {
                logger.log(Logger.INFO,"Turning off Fault Injection");
            }
            FAULT_INJECTION = inject;
         }
     }


     public void logInjection(String fault, Selector sel)
     {
         String str = "Fault Injection: triggered " + fault;
         if (sel != null)
             str += " selector [ " + sel.toString() + "]";

         Exception ex = new FaultInjectionException();
         ex.fillInStackTrace();
         logger.logStack(logger.INFO, str, ex);
     }

     public Map checkFaultGetProps(String fault, Map props)
     {
         if (!FAULT_INJECTION) return null;
         boolean ok = checkFault(fault, props);
         if (!ok) return null;
         Map m = (Map)injectionProps.get(fault);
         if (m == null) m  = new HashMap();
         return m;
     }

     public boolean checkFault(String fault, Map props)
     {
         if (!FAULT_INJECTION) return false;
         if (injections.contains(fault))
         {
             Selector s = (Selector)injectionSelectors.get(fault);
             if (s == null) {
                 logInjection(fault, null);
                 return true;
             }
             try {
                 boolean match = s.match(props, null); 
                 if (match) {
                     logInjection(fault, s);
                     return true;
                 }
                 return false;
             } catch (Exception ex) {
                 logger.logStack(Logger.WARNING,"Unable to apply fault ",
                            ex);
                 return false;
             }
         }

         return false;
     }

     public void checkFaultAndThrowIOException(String value,
                Map props)
          throws IOException
     {
         if (!FAULT_INJECTION) return;
         if (checkFault(value, props)) {
             IOException ex = new IOException("Fault Insertion: "
                   + value);
         }    
     }

     public void checkFaultAndThrowBrokerException(String value,
                Map props)
          throws BrokerException
     {
         if (!FAULT_INJECTION) return;
         if (checkFault(value, props)) {
             BrokerException ex = new BrokerException("Fault Insertion: "
                   + value);
         }    
     }

     public void checkFaultAndThrowException(String value,
                Map props, String ex_class)
          throws Exception
     {
         if (!FAULT_INJECTION) return;
         if (checkFault(value, props)) {
             // XXX use exclass to create exception
             Exception ex = new Exception("Fault Insertion: "
                   + value);
         }    
     }

     public void checkFaultAndThrowError(String value,
                Map props, String ex_class)
          throws Error
     {
         if (!FAULT_INJECTION) return;
         if (checkFault(value, props)) {
             // XXX use exclass to create exception
             Error ex = new Error("Fault Insertion: "
                   + value);
         }    
     }

     public void checkFaultAndExit(String value,
                Map props, int exitCode, boolean nice)
     {
         if (!FAULT_INJECTION) return;
         if (checkFault(value, props)) {
             if (nice) {
                 // XXX use broker method to shutdown
                 logger.log(Logger.INFO,"SHUTING DOWN BROKER BECAUSE OF"
                      + " FAULT " + value);
                 System.exit(exitCode);
             } else {
                 logger.log(Logger.INFO, "HALTING BROKER BECAUSE OF"
                      + " FAULT " + value);
                 Runtime.getRuntime().halt(exitCode);
             }
         }
     }
}     
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.