package alma.acs.nc; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import org.omg.CORBA.portable.IDLEntity; import alma.ACSErrTypeCommon.wrappers.AcsJIllegalStateEventEx; import alma.ADMINTEST1.OnOffStates; import alma.ADMINTEST1.statusBlockEvent1; import alma.ADMINTEST2.statusBlockEvent2; import alma.JavaContainerError.wrappers.AcsJContainerServicesEx; import alma.acs.component.client.ComponentClient; import alma.acs.exceptions.AcsJException; import alma.acs.logging.ClientLogManager; import alma.acs.nc.AcsEventPublisher; import alma.acs.nc.AcsEventPublisher.EventProcessingHandler; import alma.acs.nc.AcsEventSubscriber; import alma.acs.nc.NCSubscriber; import alma.acs.nc.NCPublisher; import alma.acs.nc.AcsEventSubscriber.Callback; import alma.acsnc.EventDescription; /** * Client program that sets up a supplier and a consumer in the same process, and lets them * interact for a few iterations. <code>nEvents</code> events are sent every <code>interval</code> seconds. * This is repeated <code>times</code> times. * This is currently used in conjunction with an intermediate * killing and restart of the notify service, to check that its persistence layer works * fine. * * @author rtobar, Nov 16th, 2010 * */ public class SimpleSupplierReconnClient implements Callback<EventDescription> { // For creating the clients private Logger m_logger = ClientLogManager.getAcsLogManager().getLoggerForApplication("SimpleSupplierReconnClient", false); private static final String CHANNEL_NAME = "test_reconn"; public static final String NS_RESTARTED = "NS_RESTARTED"; public static final String NS_STOPPED = "NS_STOPPED"; private volatile int received = 0; private int m_interval; private int m_nEvents; private boolean m_autoreconnect; private String m_nsAction; /** * We'll use this publisher to publish events of different types * (statusBlockEvent1, statusBlockEvent2, EventDescription). * Thus we cannot parametrize it to any of these types, but have to use the * generic base type IDLEntity or Object. */ private AcsEventPublisher<IDLEntity> m_publisher; private ComponentClient m_client; public class CallbackObject implements EventProcessingHandler<IDLEntity> { public List<Integer> m_transitions; public int m_currentEvent; public int m_nEventsSent; public int m_nEventsStored; public int m_nEventsDropped; public int m_nExceptions; protected boolean m_sent; public CallbackObject() { reset(); } public void reset() { this.m_transitions = new ArrayList<Integer>(); this.m_currentEvent = 0; this.m_nEventsSent = 0; this.m_nEventsStored = 0; this.m_nEventsDropped = 0; this.m_nExceptions = 0; this.m_sent = true; } public void eventSent(IDLEntity event) { this.m_currentEvent++; this.m_nEventsSent++; if(false == this.m_sent) { this.m_transitions.add(this.m_currentEvent); this.m_sent = true; } } public void eventStoredInQueue(IDLEntity event) { this.m_currentEvent++; this.m_nEventsStored++; if(true == this.m_sent) { this.m_transitions.add(this.m_currentEvent); this.m_sent = false; } } public void eventDropped(IDLEntity event) { this.m_currentEvent++; this.m_nEventsDropped++; if(true == this.m_sent) { this.m_transitions.add(this.m_currentEvent); this.m_sent = false; } } public void exceptionThrown() { this.m_currentEvent++; this.m_nExceptions++; if(true == this.m_sent) { this.m_transitions.add(this.m_currentEvent); this.m_sent = false; } } } private CallbackObject m_cbObj; public SimpleSupplierReconnClient(int nEvents, int interval,boolean autoreconnect,String nsAction) { m_nEvents = nEvents; m_interval = interval; m_autoreconnect = autoreconnect; m_nsAction = nsAction; m_cbObj = new CallbackObject(); m_logger.setLevel(Level.INFO); } public void createPublisherAndSubscriber() { try { m_client = new ComponentClient(m_logger, System.getProperty("ACS.manager"), "SimpleSupplierReconnClient"); m_publisher = m_client.getContainerServices().createNotificationChannelPublisher(CHANNEL_NAME, IDLEntity.class); ((NCPublisher)m_publisher).setAutoreconnect(m_autoreconnect); m_publisher.enableEventQueue(100, m_cbObj); //m_publisher.setAutoreconnect(m_autoreconnect); } catch (AcsJContainerServicesEx e) { // Silently ignore the errors } catch (AcsJException e) { // Shouldn't happen } catch (Exception e) { e.printStackTrace(); } } public void startReceiving() throws Exception { statusBlockEvent1 event1 = new statusBlockEvent1(); event1.counter1 = 0; event1.counter2 = 0; event1.counter3 = 0; event1.flipFlop = true; event1.myString = "myValue"; event1.onOff = OnOffStates.ON; event1.period = 0.2f; m_logger.info("NS action: " + m_nsAction); if(m_autoreconnect) { m_logger.info("Autoreconnection: ON"); } else { m_logger.info("Autoreconnection: OFF"); } m_logger.info("Start publishing " + String.valueOf(m_nEvents) + " events"); // publish events for(int j=0; j!=m_nEvents; j++) { try { m_publisher.publishEvent(event1); // Sleep try { Thread.sleep(m_interval * 100); } catch (InterruptedException e) { } } catch(Throwable e) { m_cbObj.exceptionThrown(); } m_logger.info("Published events at iteration " + String.valueOf(j)); } String transitions = ""; Iterator<Integer> it = m_cbObj.m_transitions.iterator(); while(it.hasNext()) { transitions += String.valueOf(it.next()) + ","; } m_logger.info("=== Number of events sent: " + String.valueOf(m_cbObj.m_nEventsSent)); m_logger.info("=== Number of events queued: " + String.valueOf(m_cbObj.m_nEventsStored)); m_logger.info("=== Number of events dropped: " + String.valueOf(m_cbObj.m_nEventsDropped)); m_logger.info("=== Number of exceptions: " + String.valueOf(m_cbObj.m_nExceptions)); m_logger.info("=== Transitions: " + transitions); if(m_autoreconnect) { if(m_nsAction.equals(NS_RESTARTED)) { if(m_cbObj.m_transitions.size() != 2) { m_logger.info("=== Wrong number of transitions: " + String.valueOf(m_cbObj.m_transitions.size()) + ". We expected 0 or 2"); } } else if(m_nsAction.equals(NS_STOPPED)) { if(m_cbObj.m_transitions.size() != 1) { m_logger.info("=== Wrong number of transitions: " + String.valueOf(m_cbObj.m_transitions.size()) + ". We expected 1"); } } else { m_logger.info("=== Wrong Notify Service action: " + m_nsAction); } } else { if(m_nsAction.equals(NS_RESTARTED)) { if(m_cbObj.m_transitions.size() != 1) { m_logger.info("=== Wrong number of transitions: " + String.valueOf(m_cbObj.m_transitions.size()) + ". We expected 1"); } } else if(m_nsAction.equals(NS_STOPPED)) { if(m_cbObj.m_transitions.size() != 1) { m_logger.info("=== Wrong number of transitions: " + String.valueOf(m_cbObj.m_transitions.size()) + ". We expected 1"); } } else { m_logger.info("=== Wrong Notify Service action: " + m_nsAction); } } } public void disconnectAndReport() throws Exception { m_publisher.disconnect(); m_client.tearDown(); } @Override public void receive(EventDescription event, EventDescription eventDescrip) { received++; m_logger.info("Received: " + received); } @Override public Class<EventDescription> getEventType() { return EventDescription.class; } /** * @param args */ public static void main(String[] args) throws Exception { if( args.length < 4 ) { System.err.println("Usage: SimpleSupplierReconnClient <# events> <# seconds between publications> <autoreconnect> <NS action>"); System.exit(1); } String nsAction = args[3]; if(nsAction.equals(SimpleSupplierReconnClient.NS_RESTARTED) == false && nsAction.equals(SimpleSupplierReconnClient.NS_STOPPED) == false) { System.err.println("Wrong NS action: " + nsAction + ". Must be: " + SimpleSupplierReconnClient.NS_RESTARTED + " or " + SimpleSupplierReconnClient.NS_STOPPED); System.exit(1); } SimpleSupplierReconnClient client = null; try { client = new SimpleSupplierReconnClient( Integer.parseInt(args[0]), Integer.parseInt(args[1]), args[2].equals("autoreconnect") || args[2].equals("AUTORECONNECT"), nsAction ); } catch(NumberFormatException e) { System.err.println("Invalid arguments, must all be integers"); System.out.println("Usage: SimpleSupplierReconnClient <# events> <# seconds between transfers> <autoreconnect>"); System.exit(1); } client.createPublisherAndSubscriber(); client.startReceiving(); client.disconnectAndReport(); System.out.println("Test finished"); } }