Solstice Enterprise Manager 4.1 Developing CORBA Applications Doc Set ContentsPreviousNextIndex


Chapter 4

Handling Events With SEM CORBA Gateway

This chapter discusses how to handle events with the SEM CORBA Gateway.

This chapter describes the following topics:

The SEM CORBA Event Gateway (EGW) is a conceptual entity comprising more than one UNIX process. The SEM CORBA Gateway consists of interfaces for registering a CORBA EventChannel, and an event distribution mechanism or CORBA-enabled Event Distribution Server (EDS) sink. The mechanism for subscribing to and unsubscribing from events is provided by the RGW.

The main component of the EGW subsystem is the CORBA-enabled EDS sink. This is similar to other EDS sinks except that the events distributed by the sink are CORBA events. It is possible for multiple instances of CORBA-enabled EDS sinks to be running on a single system, thereby allowing different CORBA clients to receive their events from different CORBA-enabled EDS sinks. However, CORBA clients are not aware of this multitude of CORBA-enabled EDS sinks nor do they need to know about it. Transparency is the outcome of this approach.


Note – Henceforth, the term EGW and CORBA-enabled EDS sinks will be used interchangeably, unless there is a need to differentiate them.

Three JIDM IDL interfaces and one SEM CORBA Gateway-specific interface are implemented by the EGW:

JIDM IDL interfaces:

SEM CORBA Gateway interface:

EventPortFactory and EventPortFinder CORBA objects are singleton objects for the entire system (in this case, one instance of Solstice EM). CORBA client applications receive their event notifications through EventPort objects, one of which is typically created for each CORBA client application.

EventPort objects are dynamically created based on the AE_Title in the criteria. The Event Port Registry (EPR) sets up a connection with the CosEventChannelAdmin::SupplierAdmin object (a part of the Event Services that is supplied by the Object Request Broker (ORB) vendor, or any other vendor) associated with the EventPort object that has the appropriate title.


FIGURE 4-1   The CORBA Event Gateway and Its Interfaces

4.1 Enabling Inter-Process Communication Between EDS Sinks and CORBA Clients

The EventPortFactory and EventPortFinder server objects are implemented in a separate stand-alone server. This server is a dæmon UNIX process and is called an EventPortRegistry object. This process also implements EventPortRegistry objects that provide inter-process communication between EDS sinks and CORBA clients.

On start up, the em_vb_corba_epr server process ((for VisiBroker) creates the EventPortRegistry CORBA object which is registered with the CORBA Naming Service. The server then proceeds to create an EventPortFinder, and finally, creates an EventPortFactory.

The following code example gives the IDL definition for EventPortRegistry.

CODE EXAMPLE 4-1   IDL Definition for EventPortRegistry
interface EventPortRegistry {
EventPort create_event_port (
                                in Key k,
                                in Criteria creation_criteria,
                                in CosEventChannelAdmin::SupplierAdmin the_supplier_admin
                        )       raises (InvalidKey, InvalidCriteria, CannotMeetCriteria, AlreadyExists);
CosEventChannelAdmin::SupplierAdmin find_event_port (
                                in Key k,
                                in Criteria the_criteria
                        )       raises (InvalidKey, InvalidCriteria, CannotMeetCriteria, NoEventPort);
EventPort find_event_port_by_ae_title(
                                in string ae_title
                        )       raises(NoEventPort);
                        
};

4.1.1 Finding an EventPort

The find_event_port_by_ae_title() registry method is used only by EDS sinks that need to know the mapping between AE_Titles and EventPorts. The find_event_port_by_ae_title() method should not be used by a CORBA client. Instead, the find_event_port() method--which returns the SupplierAdmin registered previously--should be used.

4.1.2 Creating an EventPort

A CORBA client invokes the EventPortFactory::create_event_port() method to create an EventPort. The client must supply the following creation_criteria parameters:

The following table gives reasons for the typical exceptions raised.

TABLE 4-1   Reasons for Typical Exceptions Being Raised
Exception Raised Reason
CannotMeetCriteria
Validation of the ProxyAgent object reference failed
InvalidKey
Key is not valid
AlreadyExists
Key and Criteria already exist in the registry or there is a one-to-one mapping between EventPorts and AE_Titles in the given domain



Note – To delete an EventPort field use the destroy method of the EventPort interface.

4.2 Subscribing to Events

CORBA clients listen for events by issuing a subscribe() request to the RGW to create an EFD (the definition of subscribe() is given in CODE EXAMPLE  4-2). However, before they create any EFDs, they must create and register EventPorts. When a subscribe request is processed by the CORBA RGW and sent to the MIS, the EFD attribute Secty in MIS will process this create request and send the AE_title as a listener to one of the CORBA EDS sinks.

The RGW ensures that it passes the user information in the create request. The AE_Title along with the user information and CMIS filter are passed to the EDS sink to make it an event-listener. The user information is required to enforce access control on outgoing events.

CODE EXAMPLE 4-2   IDL Definition of subscribe() (from OSIMgmtExt.idl) 
typedef string SubscriptionId;
typedef sequence<string> StringSeq;
SubscriptionId subscribe_events(
            in StringSeq event_list,
            in StringSeq object_class_list,
            in StringSeq object_name_list
        ) raises (
            OSIMgmt::AccessDenied,
            ProcessingFailure
        );

If both object_class_list and object_name_list are empty, this will cause subscription to the event_types specified in the event_list from the objects. If object_name_list is empty and object_class_list is specified, this will cause subscription to event types from objects of all classes from the object_class_list.

If the object_name_list and object_class_list are specified, this will cause subscription to event types form the objects and classes (union of object_class_list and object_name_list).

The subscription is cancelled when it is explicitly unsubscribed or when the ProxyAgent is destroyed.

4.3 Unsubscribing From Event Notifications

To explicitly unsubscribe from event notifications previously registered for, use the unsubscribe_events() method from the ProxyAgent interface:

CODE EXAMPLE 4-3   Method for Unsubscribing From Event Notifications
void unsubscribe_events(
            in SubscriptionId subscription_id
        ) raises (
            OSIMgmt::AccessDenied,
            ProcessingFailure,
            InvalidSubscriptionId
        );

4.4 Formatting Event Reports

Since JIDM does not explicitly mandate the IDL format for events, the IDL script shown in the following code example (taken from CMIExt.idl) is used for formatting event reports.

CODE EXAMPLE 4-4   IDL Event Report Format 
EventReport// Format of events received from the event_gateway
    struct EventReport {
        string event_type;
        string object_class;
        string object_name;
        string event_time;
        any    event_info;
    };
// Format of text events received from the event_gateway
struct TextEventReport {
        string event_type;
        string object_class;
        string object_name;
        string event_time;
        string event_info;
    };

4.5 Sharing Events Between Multiple Clients

Since a CORBA EventChannel can serve multiple consumers, Solstice EM event notifications can be distributed to multiple clients through the same EventChannel. In this case, the first of these clients gets the EventPort and the other clients bind to the same EventPort.

4.6 Listening to Events--Client Applications

To listen to event notifications, perform the following steps:

1. Initialize the ORB, resolve the NameServer interface and connect to the RGW

2. Get the ProxyAgent interface, osi_agent

3. Initialize, or get a reference to, an EventChannel

4. Resolve the EventPortFactory interface

5. Assign a client to the EventChannel

6. Create an EventPort

7. Subscribe to the events

The code fragments in the subsequent sections illustrate the steps listed above.


Note – Steps 1 and 3 vary from ORB to ORB and are not detailed here. Step 2 is described in Section4.2 Subscribing to Events. The rest of the code fragments follow.

4.6.1 Resolving the EventPortFactory Interface

The following code example shows how to resolve the EventPortFactory interface.

CODE EXAMPLE 4-5   Resolving the EventPortFactory Interface
/*Resolving the EventPort Factory interface */
CosNaming::Name name;
   name.length(1);
   name[0].id = CORBA::string_dup("EventPortFactory");
    try {
        CORBA::Object_var object = root_nc->resolve(name);
        JIDM::EventPortFactory_var ep_factory =
            JIDM::EventPortFactory::_narrow(object);
        if (CORBA::is_nil(ep_factory)) {
            cerr << "FAILED: Could not get EventPortFactory\n";
            TSShutdownManager::shutdown();
        }
        cout << "PASSED: Accessing the EventPortFactory\n" << flush;
    }
    catch (const CORBA::Exception& e) {
cerr << "FAILED: Could not resolve EventPortFactory name\n";
        throw;
    }

4.6.2 Assigning a Client to an EventChannel

The following code example assumes that you have already initialized an EventChannel interface pointer and that communication with the EventChannel (i.e. PushConsumer) has already been established. See Section4.6.5 Sample PushConsumer for sample code of PushConsumer.

CODE EXAMPLE 4-6   Assigning a Client to an EventChannel 
PortableServer::POAManager_var rootManager =
    root_poa->the_POAManager();
    root_poa->activate_object(&push_consumer);
    rootManager->activate();
    CosEventChannelAdmin::ConsumerAdmin_var consumer_admin =
    channel->for_consumers();
    CosEventChannelAdmin::ProxyPushSupplier_var pushSupplier =
    channel->for_consumers()->obtain_push_supplier();
    pushSupplier->connect_push_consumer(&push_consumer);
    supplier_admin = channel->for_suppliers();

4.6.3 Creating an EventPort

The following code example shows how to create an EventPort.

CODE EXAMPLE 4-7   Creating an EventPort
        key.length(1);
        key[0].id = CORBA::string_dup("OSI Management");
        key[0].kind = CORBA::string_dup("XSM environment");
        JIDM::Criteria event_criteria;
        event_criteria.length(3);
        event_criteria[0].name = CORBA::string_dup("domain title");
        event_criteria[0].value <<= (const char* )ae_title;
        // You need to pass ProxyAgent's access criteria for creating event
        // ports. This is required for enforcing connection level access
        // control.
        event_criteria[1].name = CORBA::string_dup(
            "ProxyAgent Access Criteria");
        event_criteria[1].value <<= criteria;
        event_criteria[2].name = CORBA::string_dup("EventInfo Format");
        if (format != NULL)
            event_criteria[2].value <<= (const char* )format;
        else
            event_criteria[2].value <<= (const char* )"CORBA::string";
        ep = ep_factory->create_event_port(key, event_criteria, supplier_admin);

4.6.4 Subscribing to Events

The following code example shows how to subscribe to events.

CODE EXAMPLE 4-8   Subscribing to Events 
OSIMgmtExt::ProxyAgent::StringSeq event_list;
// For all events: equivalent to CMIS Filter = and :{}
// If you want to subscribe to specific events, then uncomment the
// following line and comment out the previous line of code that
// initializes event_list to zero length
//  event_list[0] = CORBA::string_dup("\"Rec. X.721 | ISO/IEC 10165-2 : 1992\": objectCreation");
    event_list.length(0);
    
// Object Classes should be "document":oc format
 
 OSIMgmtExt::ProxyAgent::StringSeq object_class_list;
 object_class_list.length(0);
// OIs should be either in the slash format or in brace format
// Example: slash format: /systemId=name:"sesha"/logId=string:"AlarmLog"
// brace format:
// distinguishedName:{{{systemId,name:"sesha"}},{{logId,string:"AlarmLog"}}}
    OSIMgmtExt::ProxyAgent::StringSeq object_name_list;
    object_name_list.length(0);
    sid = osi_agent->subscribe_events(
                event_list, object_class_list, object_name_list);

4.6.5 Sample PushConsumer

The following code example shows how to implement PushConsumer.

CODE EXAMPLE 4-9   Sample PushConsumer  
class PushConsumerImpl : public _sk_CosEventComm::_sk_PushConsumer
{
  public:
    PushConsumerImpl()
    {
    }
    void push(const CORBA::Any& data)
    {
      /* Put Event Processing Code Here */
     }
    void disconnect_push_consumer() {
        cout << "disconnect_push_consumer() invoked" << endl;
        _boa()->shutdown();
    }
  };


Sun Microsystems, Inc.
Copyright information. All rights reserved.
Doc Set  |   Contents   |   Previous   |   Next   |   Index