/* * ALMA - Atacama Large Millimiter Array (c) European Southern Observatory, 2007 * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package alma.alarmsystem.clients.test; import java.sql.Timestamp; import java.util.concurrent.CountDownLatch; import java.util.logging.Logger; import cern.laser.source.alarmsysteminterface.FaultState; import alma.acs.component.client.ComponentClient; import alma.acs.logging.ClientLogManager; import alma.alarmsystem.clients.test.CategoryClientTest.AlarmsFromCDB; import alma.alarmsystem.source.ACSAlarmSystemInterface; import alma.alarmsystem.source.ACSAlarmSystemInterfaceFactory; import alma.alarmsystem.source.ACSFaultState; /** * An object sending alarms and used to check the system outside of tat. * * This process sends the same alarms defined in <code>CategoryClientTest</code> to use the * same CDB. * It is composed of a thread whose termination is defined by the first parameter of the * command line (i.e. a SenderMode.) * * @author almadev * */ public class AlarmSender extends Thread{ /** * The different ways of working of this client. * * @author almadev * */ private enum SenderMode { NEVER_ENDING, // Continuously send alarms TIME_LIMIT, // Send alarms for the specified time NUM_OF_ALARMS; // Send a defined number of alarms /** * The SenderMode for the passed string * * @param str The string describing the mode * @return a SenderMode for the passed string * <code>null</code> if the string does not describe any SenderMode */ public static SenderMode fromString(String str) { for (SenderMode mode: SenderMode.values()) { if (str.equalsIgnoreCase(mode.toString())) { return mode; } } return null; } } // Interval (msec) between the sending of 2 alarms private static final int TIME_INTERVAL = 250; // The component client private ComponentClient client=null; // The first parameter of the command line private SenderMode mode; // The parameter set in the command line whose meaning depends by // the mode in use private long param; // The alarm source private ACSAlarmSystemInterface alarmSource; // To signal that the thread terminated private final CountDownLatch latch = new CountDownLatch(1); /** * Constructor. * * @param mode The way of functioning * @param param Depends on the selected <code>mode</code> * It can be the number of alarms to send or the time (seconds). * It is ignored if the mode is <code>NEVER_ENDING</code> * * @see <code>ComponentClient</code> */ public AlarmSender(SenderMode mode, long param) throws Exception { if (mode!=SenderMode.NEVER_ENDING && param<=0) { throw new IllegalArgumentException(param+" is invalid for "+mode); } // Connect the component client Logger logger = ClientLogManager.getAcsLogManager().getLoggerForApplication("SourcePanel",true); String managerLoc = System.getProperty("ACS.manager"); if (managerLoc == null) { System.out.println("Java property 'ACS.manager' must be set to the corbaloc of the ACS manager!"); System.exit(-1); } this.mode=mode; this.param=param; client = new ComponentClient(logger,managerLoc,"AlarmSender"); alarmSource = ACSAlarmSystemInterfaceFactory.createSource(); } /** * Push an alarm * * @param active If true the alarm is active */ private void send_alarm(String family, String member, int code, boolean active) throws Exception { ACSFaultState fs = ACSAlarmSystemInterfaceFactory.createFaultState(family, member, code); if (active) { fs.setDescriptor(FaultState.ACTIVE); } else { fs.setDescriptor(FaultState.TERMINATE); } fs.setUserTimestamp(new Timestamp(System.currentTimeMillis())); alarmSource.push(fs); } /** * The thread sending alarms. * the termination of the thread depends on the selected SenderMode. * * The thread is composed of a loop that sends each alarms until the max * limit of alarms or time is reached or forever if the mode is * NEVER_ENDING. * * The loop send all the alarms defined in <code>AlarmsFromCDB</code> * as active then as inactive and so on. */ @Override public void run() { // The time to finish long endTime = (mode==SenderMode.TIME_LIMIT)?System.currentTimeMillis()+param*1000:Long.MAX_VALUE; // The number of alarms to send long numOfAlarms = (mode==SenderMode.NUM_OF_ALARMS)?param:Long.MAX_VALUE; long alarmsSent=0; boolean active=true; while (true) { for (AlarmsFromCDB alarm: AlarmsFromCDB.values()) { // The time has elapsed if (mode==SenderMode.TIME_LIMIT && System.currentTimeMillis()>endTime) { latch.countDown(); return; } try { send_alarm(alarm.FF, alarm.FM, alarm.FC, active); } catch (Throwable t) { System.err.println("Exception sending alarm: "+t.getMessage()); } alarmsSent++; if (mode==SenderMode.NUM_OF_ALARMS && alarmsSent>=numOfAlarms) { latch.countDown(); return; } try { Thread.sleep(TIME_INTERVAL); } catch (Exception e) {} } active=!active; } } /** * wait until the thread terminates and close the client */ public void waitAndClose() throws Exception { latch.await(); client.tearDown(); } /** * Print the USAGE string in the standard output */ public static void printUsage() { System.out.println("\nUSAGE: AlarmSender mode <value>"); System.out.print("mode: "); for (SenderMode mode: SenderMode.values()) { System.out.print(mode+" "); } System.out.println(); System.out.println("value:"); System.out.println("\tthe number of alarms to send if mode is NUM_OF_ALARMS"); System.out.println("\tthe number of seconds spent sending alarms if mode is TIME_LIMIT"); System.out.println("\n"); } public static void main(String[] args) { if (args.length<1 || args.length>2) { printUsage(); System.exit(-1); } SenderMode mode = SenderMode.fromString(args[0]); if (mode==null) { printUsage(); System.exit(-1); } System.out.println("MODE: "+mode); long param = -1; if (mode!=SenderMode.NEVER_ENDING) { if (args.length!=2) { printUsage(); System.exit(-1); } try { param = Long.parseLong(args[1]); } catch (Exception e) { printUsage(); System.exit(-1); } } AlarmSender sender=null; try { sender = new AlarmSender(mode, param); } catch (Exception e) { System.err.println("Error instantiating the AlarmSender: "+e.getMessage()); e.printStackTrace(System.err); return; } // Start the thread sender.start(); try { sender.waitAndClose(); } catch (Throwable t) { System.err.println("Exception caught closing the component client "+t.getMessage()); t.printStackTrace(System.err); } } }