package senseiTests.concurrency; import sensei.util.Configuration; import sensei.util.Error; import sensei.util.ErrorHandler; import sensei.util.logging.Logger; import sensei.util.ParameterException; import sensei.util.Parameters; import sensei.domains.DomainGroupHandlerImpl; import sensei.gmns.GroupMembershipBasicServiceImpl; import sensei.gmns.GroupMembershipNamingServiceImpl; import sensei.gmns.GroupMembershipNamingServiceFactory; import sensei.domains.DynamicSubgroupInfoAsStringImpl; import sensei.domains.GroupMonitorImpl; import sensei.middleware.gmns.GroupHandlerFactory; import sensei.middleware.gms.GroupHandler; import sensei.middleware.gmns.GroupHandlerFactoryImpl; import sensei.middleware.gmns.GroupMembershipNamingService; import sensei.middleware.domains.BehaviourOnViewChanges; import sensei.middleware.domains.DomainGroupUserBaseImpl; import sensei.middleware.domains.DomainExpulsionReason; import sensei.middleware.domains.DomainGroupHandler; import sensei.middleware.domains.GroupMonitor; import sensei.middleware.domains.MonitorException; import sensei.middleware.domains.SubgroupsHandlerException; import sensei.middleware.domains.TransactionException; import sensei.middleware.util.ObjectsHandling; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Vector; public class TestMonitor extends DomainGroupUserBaseImpl implements Runnable, ErrorHandler { DynamicSubgroupInfoAsStringImpl myInfo; Map monitors; DomainGroupHandler domainGroup; String lastInputLine; GroupMonitor monitor; int monitorNumber; ChatMember chat; Printer printer; final static int UNKNOWN = 0; final static int LOCK = 1; final static int UNLOCK = 4; final static int START_TRANSACTION = 11; final static int END_TRANSACTION = 14; final static int CREATE_MONITOR = 21; final static int REMOVE_MONITOR = 25; final static int MENU = 52; final static int QUIT = 100; public void run() { try { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); int input=UNKNOWN; printHelp(); while(input!=QUIT) { input=readInput(reader); switch(input) { case CREATE_MONITOR: createMonitor(); break; case END_TRANSACTION: endTransaction(); break; case LOCK: lockMonitor(monitor, monitorNumber); break; case MENU: printHelp(); break; case QUIT: printer.print("Leaving the group...."); domainGroup.leaveGroup(); break; case REMOVE_MONITOR: removeMonitor(monitorNumber); break; case START_TRANSACTION: startTransaction(monitor, monitorNumber); break; case UNLOCK: unlockMonitor(monitor, monitorNumber); break; case UNKNOWN: default: chat.castString(lastInputLine); } } } catch(Exception ex) { ex.printStackTrace(); System.exit(0); } } void createMonitor() throws Exception { printer.print("Creating monitor....."); GroupMonitorImpl.register(myInfo, domainGroup); } void removeMonitor(int number) throws Exception { printer.print("Removing monitor "+number+"...."); try { domainGroup.removeSubgroup(number, myInfo); } catch(SubgroupsHandlerException sex) { printer.print("Error removing the monitor. Static subgroups can not be removed!"); } } void lockMonitor(GroupMonitor who, int number) throws Exception { printer.print("Locking monitor "+number+"...."); who.lock(); printer.print("Monitor " + number + " locked!!!!"); } void unlockMonitor(GroupMonitor who, int number) throws Exception { printer.print("Unlocking monitor "+number+"...."); try { who.unlock(); printer.print("Monitor "+number+" unlocked!!!!"); } catch(MonitorException ex) { ex.printStackTrace(); printer.print("This monitor "+number+" has not the lock!"); } } void startTransaction(GroupMonitor who, int number) throws Exception { printer.print("Starting transaction "+number+"...."); domainGroup.startTransaction(who); printer.print("Transaction " + number + " started!!!!"); } void endTransaction() throws Exception { printer.print("Ending transaction ...."); try { domainGroup.endTransaction(); printer.print("Transaction ended!!!!"); } catch(MonitorException ex) { printer.print("Incorrect transaction on the given monitor"); } catch(TransactionException ex) { printer.print("System is not on a transaction"); } } int readInput(BufferedReader reader) throws IOException { do { printer.onInputRequest(); lastInputLine = reader.readLine(); printer.inputGiven(); if (lastInputLine!=null) return processLine(lastInputLine.toUpperCase()); } while(lastInputLine!=null); return QUIT; } int processLine(String line) { if (line.equals("Q")) return QUIT; else if (line.equals("?")) return MENU; else if (line.equals("E")) return END_TRANSACTION; else if (line.equals("C")) return CREATE_MONITOR; else if (line.startsWith("L")) return isValidMonitor(line.substring(1), LOCK); else if (line.startsWith("U")) return isValidMonitor(line.substring(1), UNLOCK); else if (line.startsWith("S")) return isValidMonitor(line.substring(1), START_TRANSACTION); else if (line.startsWith("R")) return isValidMonitor(line.substring(1), REMOVE_MONITOR); return UNKNOWN; } int isValidMonitor(String line, int ret) { try { Integer number = Integer.valueOf(line); monitor = (GroupMonitor) monitors.get(number); if (monitor!=null) { monitorNumber=number.intValue(); return ret; } } catch(NumberFormatException nex){} return UNKNOWN; } void printHelp() { printer.print ("----------------------- HELP --------------------------------\n" + "~~~~~~ (Lx): lock monitor --------- (Ux): unlock monitor\n" + "~~~~~~ (Sx): start Transaction ---- (E): end Transaction\n" + "~~~~~~ (C): create monitor -------- (Rx): remove monitor\n" + "~~~~~~ (?): shows this help -------- (Q): quit\n" + " The initial monitors are x=1,2,3\n" + "-------------------------------------------------------------"); } public void domainAccepted(int id) { printer.print("Member accepted; id="+id); myInfo = new DynamicSubgroupInfoAsStringImpl(String.valueOf(id)); } public void offendingSubgroup(int who, String reason) { printer.print("Detected a problem on subgroup "+who+" ("+reason+"). To be shortly expulsed..."); } public void stateObtained(boolean assumed) { printer.print("State obtained, monitor's functionality becomes available"); new Thread(this).start(); } public void domainExpulsed(DomainExpulsionReason reason) { printer.print("Member expulsed, reason="+reason.value()); System.exit(0); } public TestMonitor(Factory factory, Parameters parameters) throws ParameterException, Exception { printer = new Printer(); Error.setErrorHandler(this); String refFile = parameters.hasParameter(REFFILE)? parameters.getParameter(REFFILE) : null; String connectFile = parameters.hasParameter(CONNECT)? parameters.getParameter(CONNECT) : null; String groupName = parameters.hasParameter(GROUP)? parameters.getParameter(GROUP) : null; String name; if (parameters.hasParameter(NAME)) { name = parameters.getParameter(NAME); Logger.setLogName(name); } else name = "unknown"; domainGroup = new DomainGroupHandlerImpl(). theDomainGroupHandler(); domainGroup.setDomainGroupUser(theDomainGroupUser()); domainGroup.setBehaviourMode(BehaviourOnViewChanges.MembersOnTransferExcludedFromGroup); monitors = Collections.synchronizedMap(new HashMap()); domainGroup.setDynamicSubgroupsUser(new DynamicCreator(domainGroup, monitors, printer).theDynamicSubgroupsUser()); //A GroupHandler is required, obtaining first the appropiated factory GroupHandler toStore=null;; GroupHandlerFactory ghFactory=new GroupHandlerFactoryImpl(domainGroup).theGroupHandlerFactory(); GroupMonitorImpl impl = new GroupMonitorImpl(1, domainGroup); impl.register(); monitors.put(new Integer(1), impl.theGroupMonitor()); impl = new GroupMonitorImpl(2, domainGroup); impl.register(); monitors.put(new Integer(2), impl.theGroupMonitor()); impl = new GroupMonitorImpl(3, domainGroup); impl.register(); monitors.put(new Integer(3), impl.theGroupMonitor()); chat = new ChatMember(factory, printer); domainGroup.registerSubgroup(4, chat.theGroupMember()); if (groupName!=null) { GroupMembershipNamingService service = GroupMembershipNamingServiceFactory.load(); if (service==null) { printer.print("GroupMembershipNamingService is not available"); System.exit(0); } else { toStore=service.findAndJoinGroup(groupName, ghFactory, name, null); } } else if (connectFile==null) { toStore=GroupMembershipBasicServiceImpl.utilCreateGroup(ghFactory); if (toStore==null) { printer.print("Error, group not created"); System.exit(0); } } else { toStore=GroupMembershipBasicServiceImpl.utilJoinGroup(ObjectsHandling.readObject(connectFile), ghFactory); if (toStore==null) { printer.print("Error, member not added to group on " + connectFile); System.exit(0); } } if (refFile!=null) ObjectsHandling.writeObject(toStore, refFile); } public boolean handleError(String area, String reason) { printer.print("ERROR on "+area+": " + reason); return false; } public boolean handleException(String area, Exception exception) { exception.printStackTrace(); return handleError(area,exception.toString()); } //************************************************************************************* //**************************** READ ARGS ********************************************** //************************************************************************************* /** * Reads the command line arguments, and initializes the * Configuration singleton class; arguments are translated into the Parameter class and * returned. * It returns null if arguments are incorrect or they do not require any GMNS processing **/ public static Parameters readArgs(String args[]) { Parameters ret = null; try { Vector params=new Vector(); params.add(CONF); params.add(GROUP); params.add(NAME); params.add(CONNECT); params.add(REFFILE); params.add(HELP); ret = new Parameters(args, params, null,0,0); if (ret.hasParameter(HELP)) { ret=null; help(); } else { if (ret.hasParameter(CONF)) Configuration.getSingleton(ret.getParameter(CONF), ret.getDefinitions()); else Configuration.getSingleton(ret.getDefinitions()); if (ret.hasParameter(GROUP)) if (ret.hasParameter(CONNECT)) throw new ParameterException(CONNECT + " option not compatible with " + GROUP); else if (ret.hasParameter(REFFILE)) throw new ParameterException(REFFILE + " option not compatible with " + GROUP); } } catch (ParameterException pex) { System.err.println("Arguments error: " + pex.getMessage()); help(); } catch (IOException ioex) { System.err.println("Error reading the configuration file: " + ioex.getMessage()); } return ret; } //************************************************************************************* //**************************** HELP *************************************************** //************************************************************************************* static void help() { System.out.println("arguments: [options...]\n\tOptions:\n\t\t" + CONF + "=configuration file\n\t\t\t--> sensei properties file \n\t\t" + GROUP + "=group name\n\t\t\t--> group name if a GMNS service is running \n\t\t" + NAME + "=name\n\t\t\t--> Identifies this monitor (logging & GMNS) \n\t\t" + CONNECT + "=group member reference file\n\t\t\t--> file with the reference of a group member to join \n\t\t" + REFFILE + "=reference file\n\t\t\t--> file to include the reference of this server\n\t\t" + HELP + "\n\t\t\t--> shows this brief help \n\n\t" ); } //************************************************************************************* //**************************** DATA MEMBERS ******************************************* //************************************************************************************* static final String CONF = "config"; static final String GROUP = "group"; static final String NAME = "name"; static final String CONNECT = "connect"; static final String REFFILE = "reffile"; static final String HELP = "help"; }