Dynamic Logging & the CORBA Notification Service by Tarak Modi Listing One // domain, type, event name EventType type = new EventType ("example", "test"); FixedEventHeader fixed = new FixedEventHeader (type, "event"); // variable header, NV Pairs // Let's add a priority QoS Property variable[] = new Property[1]; variable[0] = new Property (); variable[0].name = Priority.value; variable[0].value = orb.create_any (); variable[0].value.insert_short ((short) 3); // Filterable data, NV Pairs // Remember these are user defined and can be anything. Property filterable[] = new Property[1]; filterable[0] = new Property (); filterable[0].name = "eventnumber"; filterable[0].value = orb.create_any (); filterable[0].value.insert_long ((long)11); // Event Data org.omg.CORBA.Any data = orb.create_any (); data.insert_string("Hello World"); // We have finished creating all the distinct pieces // Now let's create a structured event StructuredEvent event = new StructuredEvent (); event.header = new EventHeader (fixed, variable); event.filterable_data = filterable; event.remainder_of_body = data; Listing Two // This is the class that applications use for logging messages. import org.omg.CosNotification.*; import org.omg.CosNotifyComm.*; import org.omg.CosNotifyChannelAdmin.*; public class Tracer extends _StructuredPushSupplierImplBase { private StructuredProxyPushConsumer sp; private boolean required = false; private org.omg.CORBA.ORB orb = null; public Tracer(org.omg.CORBA.ORB orb) throws TraceException { // save the orb reference for later this.orb = orb; initialize(); } // shutdown this instance of tracer public void destroy() { // delegate to finalize() finalize(); sp = null; } public void finalize() { // Disconnect from the channel if we need to. if(sp != null) sp.disconnect_structured_push_consumer(); } // not implemented public void disconnect_structured_push_supplier () { } // This is where Tracer gets its "smarts" from. This function is called // any time the aggregate of event subscribed to on the channel. public void subscription_change (EventType added[], EventType removed[]) { //System.out.println("Received Subscription change..."); for( int i = 0; i < added.length; i++ ) { if( added[i].domain_name.equals ("Tracer") && added[i].type_name.equals ("") ) { //System.out.println("Turning events on..."); // Synchronize to serialize the "required" flag access synchronized(this) { required = true; } break; } } for( int i = 0; i < removed.length; i++ ) { if( removed[i].domain_name.equals ("Tracer") && removed[i].type_name.equals ("") ) { //System.out.println("Turning events off..."); // Synchronize to serialize the "required" flag access synchronized(this) { required = false; } break; } } } // Synchronize to serialize the "required" flag access synchronized public boolean on() { return required; } // This method takes the message and tracelevel parameters and // constructs a structured event. public void trace(String msg, int tracelevel) throws TraceException { if(sp == null) { throw new TraceException("Error: No connection"); } boolean req = on(); // If anyone is interested in these events the // required flag would be true. if( req ) { //System.out.println("Logging message: " + msg); EventType type = new EventType ("Tracer", ""); FixedEventHeader fixed = new FixedEventHeader (type, "event"); // variable header, NV Pairs Property variable[] = new Property[0]; // Filterable data, NV Pairs // Use the tracelevel here Property filterable[] = new Property[1]; filterable[0] = new Property (); filterable[0].name = "tracelevel"; filterable[0].value = orb.create_any (); filterable[0].value.insert_long(tracelevel); // Event Data org.omg.CORBA.Any data = orb.create_any (); data.insert_string(msg); // Put everything together... StructuredEvent event = new StructuredEvent (); event.header = new EventHeader (fixed, variable); event.filterable_data = filterable; event.remainder_of_body = data; try { // Off the event goes... sp.push_structured_event(event); } catch(org.omg.CosEventComm.Disconnected e) { throw new TraceException("Error: Reconnect required"); } } } ///////////////////////// // Private Methods... ///////////////////////// private void initialize() throws TraceException { EventChannel channel = getChannel(); connect(channel); } private EventChannel getChannel() throws TraceException { // Get a reference to the notification service org.omg.CORBA.Object obj = null; try { obj = orb.resolve_initial_references("NotificationService"); } catch( org.omg.CORBA.ORBPackage.InvalidName ex ) { throw new TraceException("Error: Failed to resolve Notification Service"); } // Get the event channel factory from the service EventChannelFactory factory = EventChannelFactoryHelper.narrow(obj); // Get the event channel from the factory EventChannel channel = null; try { channel = factory.get_event_channel(0); } catch(ChannelNotFound ex) { // Channel is not found, let's create a new one... // Create a channel with no QoS or admin properties. Property[] qosProp = new Property[0]; Property[] admProp = new Property[0]; org.omg.CORBA.IntHolder id = new org.omg.CORBA.IntHolder (); try { channel = factory.create_channel(qosProp, admProp, id); } catch( UnsupportedQoS exc ) { } catch( UnsupportedAdmin exc ) { } } return channel; } private void connect(EventChannel channel) throws TraceException { // Get the default supplier admin object for this channel SupplierAdmin admin = channel.default_supplier_admin (); // Now ask the admin for a reference to a push consumer proxy ClientType ctype = ClientType.STRUCTURED_EVENT; org.omg.CORBA.IntHolder pid = new org.omg.CORBA.IntHolder (); ProxyConsumer proxy = null; try { proxy = admin.obtain_notification_push_consumer (ctype, pid); } catch( AdminLimitExceeded ex ) { throw new TraceException("Error: Max number of proxies exceeded"); } sp = StructuredProxyPushConsumerHelper.narrow (proxy); try { // connect to the channel sp.connect_structured_push_supplier(this); // Inital "smarts" // See if any TracerMons are there listening for Tracer events EventType types[] = sp.obtain_subscription_types(org.omg.CosNotifyChannelAdmin.ObtainInfoMode.ALL_NOW_UPDATES_ON); //System.out.println("Total events being subscribed to = " + types.length); for( int i=0; i