3D PLM Enterprise Architecture

Middleware Abstraction - ENOVIA Event Model

Subscribing Explicitely to Events

Working with events and subscribers
Use Case

Abstract

This article discusses the CAAVpiSimpleSubscription use case. This use case explains how to subscribe explicitly to events, taking the example of events fired by the Login Session object.

What You Will Learn With This Use Case

This use case is intended to show you different manners that can be used to explicitly subscribe to events and how to implement the dedicated callback interfaces to handle these events when they are raised.

[Top]

The CAAVpiSimpleSubscription Use Case

CAAVpiSimpleSubscription is a use case of the CAAVPMInterfaces.edu framework that illustrates VPMInterfaces framework capabilities.

[Top]

What Does CAAVpiSimpleSubscription Do

The CAAVpiSimpleSubscription use case processes to two different kinds of explicit subscriptions, then raises the events that have been subscribed to, and finally calls the corresponding subscribers back.

The CAAVpiSimpleSubscription use case is related to the CAAVpiEventsObjects.m module where the subscriber class CAAVpiSimpleSubscriber is defined.

More precisely, the program:

[Top]

How to Launch CAAVpiSimpleSubscription

To launch CAAVpiSimpleSubscription, you will need to set up the build time environment, then to compile CAAVpiSimpleSubscription along with its prerequisites, to set up the run time environment, and then to execute the use case [1].

Launch the use case as follows:

[Top]

Where to Find the CAAVpiSimpleSubscription Code

The CAAVpiSimpleSubscription use case is made of a main named CAAVpiSimpleSubscription.cpp located in the CAAVpiSimpleSubscription.m module and a class named CAAVpiSimpleSubscriber located in the CAAVpiEventObjects.m module of the CAAVPMInterfaces.edu framework.

Windows InstallRootDirectory\CAAVPMInterfaces.edu\CAAVpiSimpleSubscription.m\(main)
InstallRootDirectory\CAAVPMInterfaces.edu\CAAVpiEventObjects.m\(subscriber class)
Unix InstallRootDirectory/CAAVPMInterfaces.edu/CAAVpiSimpleSubscription.m/(main)
InstallRootDirectory/CAAVPMInterfaces.edu/CAAVpiEventObjects.m/(subscriber class)

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

[Top]

Step-by-Step

There are seven main steps in the CAAVpiSimpleSubscription use case:

  1. Create a Session
  2. Create a Login Session
  3. Get the Event Manager
  4. Create a late and an early Subscribers
  5. Subscribe to event SaveLoginSesion on the instance of the Login Session for the two kinds of Subscribers
  6. Save the Login Session
  7. Close the Sessions

We will now comment each of these sections in detail.

[Top]

Create a Session

...
    // ---------------------------
    // --> 1. Open a VPM Session
    // ---------------------------
    //
    cout << "main: Open VPM Session ... " << endl;
    VPMSession* pSession = VPMSession::OpenSession();
    if ( NULL == pSession ) 
    {
        cout << "Unable to Open a VPM Session" << endl;
        return 1;
    }
    cout << "main: Open VPM Session done " << endl << endl;
...

[Top]

Create a Login Session

...
    // -------------------------------
    // --> 2. Login Session creation
    // -------------------------------
    //
    cout << "main: Create LoginSession ... " << endl;
    const int NetWorkCommunication = 0;
    CATIVpmLoginSession_var spLoginSession;
    Rc = pSession->CreateLoginSession( "MyUserID", "MyPassword", "MyRoleName", NetWorkCommunication, spLoginSession );
    if ( FAILED(Rc) )
    {
        cout<<"Unable to Create Login Session"<<endl;
        return 2;
    }
    cout << "main: Create LoginSession done " << endl << endl;
...

[Top]

Get the Event Manager

...
    // ------------------------------
    // --> 3. Get the Event Manager                                   
    // ------------------------------
    //
    ENOVIEventManager_var spEventManager;
    Rc = spLoginSession->get_ENOVEventManager( spEventManager );
    if ( FAILED(Rc) )
    {
	cout<<"Unable to get the Event Manager from the Session"<<endl;
	return 5;
    }
    cout << "main: Get Event Manager done " << endl << endl;
...

The Event Manager is used to subscribe to events on object types or instances. By implementing appropriate callback interfaces declared by the ENOVIA domains (here referred to as early subscribing) or a generic callback interface named ENOVISubscriberEvent (here referred to as late subscribing), clients can do some actions when events are raised by a given type or a given instance of object.

[Top]

Create a late and an early Subscribers

As already stated, a late Subscriber is a class that implements the generic ENOVISubscriberEvent callback interface, which provide only two methods onReceive and onKo. The method onReceive is used to handle whatever event is raised. Consequently the implementation must take care of the name of the event and its publisher (available on the ENOVIEvent pointer) to behave as appropriate.

An early Subscriber is a class that implements the specific callback interface provided by the publisher of the events of interest. For this use case, we are interested in the events emitted by the Session. Hence the early Subscriber will implement the ENOVISessionEvent callback interface.

For simplicity, in this use case, the class CAAVpiSimpleSubscriber implements both ENOVISubscriberEvent and ENOVISessionEvent. To distinguish the two kinds of subscriber instances, a different name is given to these instances. This implementation can be found in the CAAVpiEventObjects module.

In this step as soon as the subscribers are created, a query interface is carried out to retrieve the appropriate smart pointers the Subscribe method is waiting for.

...
    // -----------------------------
    // --> 4. Subscribers creation
    // --> 4a. Late Subscriber
    // -----------------------------
    //
    CAAVpiSimpleSubscriber* pLateSubscriber = new CAAVpiSimpleSubscriber("Late Subscriber");
    ENOVISubscriberEvent_var spLateSubscriber ( pLateSubscriber );
    if ( NULL_var == spLateSubscriber )
    {
	cout<<"Unable to get a handler on Late Subscriber"<<endl;
        return 6;
    }
    pLateSubscriber->Release();
    pLateSubscriber = NULL;
    cout << "main: Get ENOVISubscriberEvent handler on Late Subscriber done " << endl;

    //
    // --------------------------
    // --> 4b. Early Subscriber
    // --------------------------
    //
    CAAVpiSimpleSubscriber* pEarlySubscriber = new CAAVpiSimpleSubscriber("Early Subscriber");
    ENOVISessionEvent_var spEarlySubscriber ( pEarlySubscriber );
    if( NULL_var == spEarlySubscriber )
    {
 	cout<<"Unable to get a handler on Early Subscriber"<<endl;
        return 7;
    }
    pEarlySubscriber->Release();
    pEarlySubscriber = NULL;
    cout << "main: Get ENOVISessionEvent handler on Early Subscriber done " << endl;
...

[Top]

Subscribe to event SaveLoginSesion on the instance of the Login Session for the two kinds of Subscribers

This step performs the subscriptions. They are subscriptions on instance as the argument for the publisher is the ENOVIPublisher view of the just created Login Session.
...
    // ----------------------------------------
    // --> 5. Subscribe on Save Login Session 
    // ----------------------------------------
    //
    EventName = "SaveLoginSession";
    ENOVIPublisher_var spEventPublisherInstance = spLoginSession;
    if ( NULL_var == spEventPublisherInstance )
    {
        cout<<"Unable to get a handler on Login Session"<<endl;
        return 8;        
    }
    cout << "main: Get ENOVIPublisher handler on Login Session done " << endl;

    //
    // ------------------------------------------------------------
    // --> 5a. LATE MODE Subscription by Subscriber 1 on INSTANCE
    // ------------------------------------------------------------
    //
    Rc = spEventManager->Subscribe( EventName, spEventPublisherInstance, spLateSubscriber, &cookie, ENOVIEvent::EventFireAfter );
    if ( FAILED(Rc) )
    {
	cout<<"Unable to late subscribe on SaveLoginSession"<<endl;
	return 9;
    }
    cout << "main: Subscribe on instance to SaveLoginSession (after) in Late Mode done " << endl;
    
    //
    // -------------------------------------------------------------
    // --> 5b. EARLY MODE Subscription by Subscriber 2 on INSTANCE
    // -------------------------------------------------------------
    //
    Rc = spEventManager->Subscribe( EventName, spEventPublisherInstance, spEarlySubscriber, IID_ENOVISessionEvent, &cookie, ENOVIEvent::EventFireBefore );
    if ( FAILED(Rc) )
    {
	cout<<"Unable to early subscribe on SaveLoginSession"<<endl;
	return 10;
    }
    cout << "main: Subscribe on instance to SaveLoginSession (before) in Early Mode done " << endl << endl;
...

[Top]

Save the Login Session

The interest of that step is to see the traces at execution time: you should see the two subscribers being called back on the right method at the right time (one before and one after the event is raised).

...
    //
    // --------------------------------
    // --> 6. Fire Save Login Session
    // --------------------------------
    //
    cout << "main: Save Login Session ... " << endl;
    Rc = spLoginSession->Save();
    if ( FAILED(Rc) )
    {
	cout<<"Unable to Save Login Session"<<endl;
	return 11;
    }
    cout << "main: Save Login Session done " << endl << endl;
...

[Top]

Close the Sessions

Each opened session must be closed as followed:

...
    //
    // --------------------------------------------
    // --> 7. Close Login Session and VPM Session
    // --------------------------------------------
    //
    Rc = spLoginSession->Close();
    if ( FAILED(Rc) )
    {
	cout<<"Unable to Close Login Session"<<endl;
	return 12;
    }
    cout << "main: Close Login Session done " << endl;

    VPMSession::CloseSession();
    cout << "main: Close VPM Session done " << endl;
...

This step concludes the CAAVpiSimpleSubscription use case.

[Top]

In Short

This use case has demonstrated two ways to explicitly subscribe to events and how to be called back when they are raised.

[Top]


References

[1] Building and Launching a CAA V5 Use Case
[2] The ENOVIA Event Model
[Top]

History

Version: 1 [Oct 2003] Document updated
Version: 1 [Oct 2001] Document created
[Top]

Copyright © 2003, Dassault Systèmes. All rights reserved.