// used to be FMCore package org.fi; import org.fi.*; import java.io.*; import java.util.Random; import org.fi.FMJoinPoint.*; import org.apache.xmlrpc.common.TypeConverterFactoryImpl; import org.apache.xmlrpc.server.PropertyHandlerMapping; import org.apache.xmlrpc.server.XmlRpcServer; import org.apache.xmlrpc.server.XmlRpcServerConfigImpl; import org.apache.xmlrpc.webserver.WebServer; //JINSU import org.apache.xmlrpc.server.*; //import org.apache.cassandra.Util; // ****************************************************************** // Important note on FMServer usage: // FMServer should be just a server that passes decision to its // members. For example, to decide whether we should do a fault // injection or not, it just calls ManualFI .. later we want to do // AutoFI for example. // And also, to do modeling, we will use the Frog class // ****************************************************************** // public class FMServer implements FMProtocol { public class FMServer { public static boolean debug = false; //public static boolean debug = true; // private FrogServer frogServer; // the failure types // transient = exception // persistent = baddisk public static enum FailType { CRASH, BADDISK, EXCEPTION, RETFALSE, CORRUPTION, NONE; } // *********************************************************** public FMServer() { // also check frogHooks.aj is enabled!! // frogServer = new FrogServer(); } // ####################################################################### // ####################################################################### // #### #### // #### F M S E R V E R S E R V I C E #### // #### #### // ####################################################################### // ####################################################################### // *********************************************************** private static synchronized FailType syncedSendContext(FMAllContext fac) { // 1. print all context if (debug) printAllContext(fac); // 2. mark that we "cover" this, although we haven't excercised this // (only if we want to compare, but normally, let's jsut comment this out // otherwise to many output in tmp-fi-out) Coverage.recordBeforeFilter(fac); // 3. we always go to the failure logic, but check if we should // fail or not later, so that we can get the coverage point FailType ft = doFail(fac); // print and return if (debug || true) printFailure(fac, ft); return ft; } // *********************************************************** private static void printFailure(FMAllContext fac, FailType ft) { if (ft == FailType.NONE) return; Util.MESSAGE("Server: I'm failing this (see above) [ft:" + ft + "]"); } // *********************************************************** private static void printAllContext(FMAllContext fac) { // print context System.out.println("Receive sendContext: [" + fac.ctx.getCutpointRandomId() + "]\n"); System.out.println(fac.ctx); // print joinpoint System.out.println(fac.fjp); // print stack System.out.println(fac.fst); } // *********************************************************** // doFail should consult the model check, // but if we want to drive the model checker with specific // manual stuffs, then we also consult the doFail // *********************************************************** private static FailType doFail(FMAllContext fac) { FailType ft = FailType.NONE; // By default we want to call the fmlogic ft = FMLogic.run(fac); // or do manual stuffs // boolean isFail = manualFI.doFail_02(fac); // fail03: fail03 with more filters, very specific // boolean isFail = manualFI.doFail_03(fac); // this is sufficient for doFail 01 // ft = manualFI.doFail_01(fjp, ctx, fst); return ft; } // *********************************************************** /* public void sendFrogEvent(FMJoinPoint fjp, FMStackTrace fst, FrogEvent fev) { if (frogServer == null) { Util.WARNING("Please instantiate FrogServer first, see FMServer"); return; } System.out.println("Receive sendFrogEvent: "); // print joinpoint System.out.println(fjp); // print stack System.out.println(fst); // System.out.format("++ haha %s \n", fev); frogServer.processFrogEvent(fjp, fst, fev); } */ // ####################################################################### // ####################################################################### // #### #### // #### X M L R P C #### // #### #### // ####################################################################### // ####################################################################### public final static int PORT = 16000; // *********************************************************** public void start() { try { System.out.println("- Starting XML-RPC Server..."); WebServer webServer = new WebServer(PORT); XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer(); PropertyHandlerMapping phm = new PropertyHandlerMapping(); phm.addHandler("FMServer", org.fi.FMServer.class); xmlRpcServer.setHandlerMapping(phm); XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig(); serverConfig.setEnabledForExtensions(true); serverConfig.setContentLengthOptional(false); System.out.println("- Waiting for incoming ..."); webServer.start(); System.out.println("- After webserver.start ..."); } catch (Exception e) { Util.EXCEPTION("Can't start server", e); Util.FATAL("Can't start server"); } } // ************************************ // THis is the send context via XML RPC // ************************************ public int sendContext(int randId) { // System.out.format("- Receveived %d \n", randId); return syncedSendContext(randId); } // ************************************ // It is important for send context to be synchronized AND static !! // the reason is that web xml services always create a new FMServer // to process a request. So if we don't create this as static, // the synchronization is useless! // ************************************ private static synchronized int syncedSendContext(int randId) { DataInputStream dis = Util.getRpcInputStream(randId); FMAllContext fac = new FMAllContext(); try { fac.readFields(dis); } catch (Exception e) { Util.EXCEPTION("fac.readFields", e); Util.FATAL("fac.readFields"); } FailType ft = syncedSendContext(fac); int rv = Util.failTypeToInt(ft); return rv; } // ####################################################################### // ####################################################################### // #### #### // #### H A D O O P R P C #### // #### #### // ####################################################################### // ####################################################################### /* public final static String bindAddr = "localhost"; // *********************************************************** public long getProtocolVersion(String protocol, long clientVersion) throws IOException { return FMProtocol.versionID; } // *********************************************************** public void initialize() throws InterruptedException { System.out.println("FMServer: Init ..."); Configuration conf = new Configuration(); Server server; try { server = RPC.getServer(this, bindAddr, port, conf); // this runs forever ... server.start(); server.join(); System.out.println("FMServer: After server join ..."); } catch (IOException e) { System.out.println("FMServer: Exception ..."); e.printStackTrace(); } } // *********************************************************** public FailType sendContext(FMJoinPoint fjp, FMContext ctx, FMStackTrace fst) { FMAllContext fac = new FMAllContext(fjp, ctx, fst); return syncedSendContext(fac); } */ }