Solstice Enterprise Manager 4.1 Developing CORBA Applications | ![]() ![]() ![]() ![]() ![]() |
Managing Networks With SEM CORBA Gateway
This chapter discusses network management through the SEM CORBA Gateway.
This chapter describes the following topics:
3.1 General Concepts
The SEM CORBA Gateway provides internetworking between CORBA-based management stations and Solstice Enterprise Manager (Solstice EM). Since Solstice EM provides Solstice EM south-bound interfaces to various network technologies (such as SNMP, CMIP and RPC), the SEM CORBA Gateway also accommodates these technologies.
The following sections are adapted from Developing C++ Applications guide for Solstice Enterprise ManagerTM 4.1; refer to the guide for more information.
3.1.1 Modeling Objects
Network management in the Solstice EM environment follows the ISO network management model. This object-oriented model is based around manager and agent applications that exchange network management information. To manage your resources in the Solstice EM environment, you must define an object model for those resources. The object model defines the characteristics of resources your application will manage.
3.1.2 Managers
A manager performs the following functions:
- Issuing management requests to one or more agents
- Collecting and filtering information from agents
- Presenting information about the managing system to human operators
A manager receives information from agents in the form of notifications and responses, as follows:
- Notifications - A notification is an unsolicited message sent to the manager indicating that a change has occurred in the managed resource.
- Responses - A response is a message sent in response to a management request containing either the information the manager requested or a confirmation that the request was carried out.
A manager resides in the managing system.
3.1.3 Agents
An agent acts as an intermediary between a manager and managed resources. An agent responds to requests and issues notifications. Each agent acts as an interpreter and a filter, sending commands to each of the managed resources it controls to get the data it requires. Each agent in a managed system is responsible for carrying out management directives to control or return information from managed resources.
An agent can reside in a managed resource or be located elsewhere and operate remotely.
3.1.4 Managed Resources
A managed resource is any network resource that can be managed. The resource can be a physical device such as a host, server, router, or subnet, or it can be a conceptual entity such as a line, a queue, or some other aspect of network operation that must be managed.
3.1.5 Managed Objects
The ISO management model on which Solstice EM is based is object oriented. According to this model, a managed resource is represented as a managed object. A managed object is a software abstraction of a managed resource. The managed object presents the information needed to manage the resource. A managed resource may be represented by one or more managed objects. An agent typically contains or provides views of many managed objects.
3.1.6 Management Protocols
A management protocol is a set of rules that specifies how information is exchanged between two entities that are communicating, such as a manager and an agent. A management protocol provides the common language required to enable managers and agents to exchange information.
A management protocol defines:
- The types of management requests and responses that agents and managers are allowed to issue.
- The syntax and encoding of each type of request and response.
- The sequence in which management requests and responses are allowed to be issued.
3.1.7 Concepts Specific to CORBA and TMN
Some concepts are specific to CORBA and Telecommunication Management Network (TMN). The objects (both managed and manager) are grouped into domains according to some specific criteria. Domains are identified by titles and are individually accessible using titles. Hence, it is necessary for an entity (manager or managed) to gain access to the domain in order to access the object.
Access to a domain is granted through a port (not to be confused with TCP/IP ports). Two types of ports are defined in the JIDM standards, the EventPort and the DomainPort.
When a manager (or agent) gains access to a managed (or manager) domain, a session has been established. A session can be released (terminated), after which no further communication can take place. Establishing a session involves checking for the user's authorization and privileges. Any number of sessions can be active at any given time between any two objects.
3.2 Operating on CORBA Clients and Objects
CORBA clients first need to get access to the domain (or get connected to the gateways) so that they can operate on objects. The operations on the objects can be carried out either synchronously or asynchronously. These operations basically map to the CMIS services on managed objects. Each of these operations is explained with examples in the following sections.
Note The operation of creating objects requires two different functions for synchronous and asynchronous creation, while other operations on the objects requires only one function, the end_of_replies_handler, based on whose value the operation on the object is synchronous or asynchronous.
3.2.1 Operating Asynchronously and Synchronously
The LinkedReplyHandler and EndOfRepliesHandler interfaces defined in the JIDM standards enable the clients or applications to handle the replies sent back by the gateways.
These two interfaces must be implemented by the client or manager application. CMIS functions such as cmis_get() require references to these two interfaces to be passed as arguments. The LinkedReplyHandler interface handles replies sent back (both error and no error responses) and is mandatory. The EndOfRepliesHandler interface is optional; if implemented and passed as an argument to the CMIS function, it will render the CMIS operation asynchronous; if NULL is passed in place of this argument, the operation will be treated as synchronous and client applications will be blocked until a reply or an error message is received.
![]()
FIGURE 3-1 get Asynchronous OperationIn a get asynchronous operation, the manager application creates both LinkedReplyHandler and EndOfRepliesHandler.
When the CORBA application does a cmis_get(), it passes the reference for LinkedReplyHandler along with the other arguments to the SEM CORBA Gateway. The Gateway passes on the request to Solstice EM MIS. In an asynchronous operation the CORBA manager application is not blocked, and can continue processing.
When a reply from the Solstice EM MIS corresponds to the get request, the reference to EndOfRepliesHandler that was passed by the CORBA manager application is used to send the reply back to the application, by executing the end_of_replies().
Note All other operations are similar to the get operation except the create operation. The cmis_create_sync (synchronous create) command does not have LinkedReplyHandler nor EndOfRepliesHandler, whereas cmis_create() (asynchronous create) has only LinkedReplyHandler.
If there is an error in processing the request, the SEM CORBA Gateway executes either send_subtree_error() or send_no_error(), depending on the error condition.
![]()
FIGURE 3-2 get Synchronous OperationIn a get synchronous operation, the manager application creates only the LinkedReplyHandler and a NULL is passed in place of EndOfRepliesHandler. Once the request is sent to the Solstice EM MIS, communication between the CORBA manager application and the SEM CORBA Gateway is blocked.
When a reply is received, it is forwarded to the CORBA manager application by executing send_reply().
If there is an error in processing the request, the SEM CORBA Gateway executes either send_subtree_error() or send_no_error(), depending on the error condition.
3.2.2 Handling Replies and Errors in Client Applications
The replies sent back by the SEM CORBA Gateway in response to a request are handled by the send_reply() method exposed by the LinkedReplyHandler interface. The send_reply() method returns the object interface, the object Id, the time at which the command was handled, and the result of the command.
The error condition returned by the SEM CORBA Gateway is handled by the send_subtree_error() or the send_mo_error() method.
The following code example shows the implementations of send_reply(), send_subtree_error() and send_mo_error() for a cmis_get() command.
3.2.3 Creating Objects
The JIDM standard specifies two ways of creating managed objects:
- Using the ManagedObjectFactory interface
- Using the ProxyAgent interface
The SEM CORBA Gateway supports creating managed objects using only the ProxyAgent interface.
Managed objects can be created synchronously or asynchronously.
Synchronous creation of managed objects uses the cmis_create_sync() function of the OSIMgmt::ProxyAgent interface.
Asynchronous creation of managed objects uses the cmis_create() function of the OSIMgmt::ProxyAgent interface.
cmis_create_sync() and cmis_create() return the following conditions to indicate errors:
- Duplicate Invocation
- Mistyped Argument
- Resource Limitation
- Unrecognized Operation
- Access Denied
- Class Instance Conflict
- Duplicate Managed Object Instance
- Invalid Attribute Value
- Invalid Object Instance
- Missing Attribute Value
- No Such Attribute
- No Such Object Class
- No Such Object Instance
- No Such Reference Object
- Processing Failure
- Processing Failure Empty
CODE EXAMPLE 3-2 is a complete program that does exception handling for all the ORB and JIDM operations. It creates a managed object with the following instance name:
/systemId=name:<MIS-HOST>/emApplicationDatabase="TEST1"
CODE EXAMPLE 3-2 Creating Managed Objects
// Copyright 05/25/99 Sun Microsystems, Inc. All Rights Reserved. #pragma ident "@(#)create_client.cc 1.1 99/05/25 Sun Microsystems" #include <unistd.h> #include <iostream.h> #ifdef ORBACUS #include <OB/CORBA.h> #include <CosNaming.h> #include <jidm/OSIMgmt.h> #include <jidm_ext/ASN1TypesExt_skel.h> #else #ifdef ORBIX #include <omg/orb.hh> #include <CosNaming.hh> #include <jidm/OSIMgmt.hh> #include <jidm_ext/ASN1TypesExtS.hh> #else #include <cos/CosNaming_c.hh> #include <jidm/OSIMgmt_c.hh> #include <jidm_ext/ASN1TypesExt_s.hh> #endif #endif #include <em_c++utils/dynamic_output_string_stream.hh> #include <em_c++utils/ts_shutdown_manager.hh> #include "corba_gateway_connection.hh" #include "create_linked_reply_handler_impl.hh" int main(int argc, char **argv) { if (argc < 4) { cout << "create_client -SVCnameroot <Root Naming Context>" << " <MIS host name> [-ORBagentaddr <I/P address>/<host name>]\n" << flush; exit(1); } CORBA::ORB_var orb; PortableServer::POA_var root_poa; PortableServer::POA_var action_poa; PortableServer::POAManager_var poa_manager; TSShutdownManager& shutdown_mgr = TSShutdownManager::instance(); SampleShutdownCallback* sample_shutdown_cb = new SampleShutdownCallback(); shutdown_mgr.add_callback(sample_shutdown_cb); //**************************************************** // STEP NO 1: Initialize the ORB, // Get NameService and root naming context //**************************************************** try { orb = CORBA::ORB_init(argc, argv); cout << "PASSED: Resolving RootPOA reference" << endl; root_poa = PortableServer::POA::_narrow(orb->resolve_initial_references("RootPOA")); if (CORBA::is_nil(root_poa)) { cout << "Unable to get RootPOA context!!" << endl; exit(1); } poa_manager = root_poa->the_POAManager(); // Create policies for our action POA CORBA::PolicyList policies; policies.length(1); policies[(CORBA::ULong)0] = root_poa->create_lifespan_policy(PortableServer::TRANSIENT); action_poa = root_poa->create_POA("action_poa", NULL, policies); } catch(const CORBA::Exception& e) { cerr << "FAILED: Caught CORBA Exception " << endl; exit(1); } CORBAGatewayConnection cgw_connection(); //******************************************************** // STEP NO 2: Get ProxyAgentFinder //******************************************************** JIDM::ProxyAgentFinder_var proxy_agent_finder = cgw_connection.get_proxy_agent_finder(); JIDM::ProxyAgent_var proxy_agent; try { proxy_agent = cgw_connection.get_proxy_agent(); } catch ( const CORBA::Exception& e ) { cerr << "FAILED: Unable to obtain proxy agent:\n " << flush; } try { OSIMgmt::ProxyAgent_var osi_agent= OSIMgmt::ProxyAgent::_narrow(proxy_agent); //******************************************************** // STEP NO 3: Build the Managed Object name to be created //******************************************************** const char* interface_name = (const char *)"emApplicationDatabase"; DynamicOutputStringStream tmp_buf; tmp_buf << "systemId=name:'" << argv[3] << "'"; CosNaming::Name object_name(3); object_name.length(3); object_name[0].id = (const char *)"root"; object_name[1].id = (const char *)tmp_buf.get_string(); object_name[2].id = (const char *)"emApplicationType='TEST1'"; OSIMgmt::CreationKind kind = OSIMgmt::simple; // dummy access control X711CMI::AccessControlTypeOpt access_control; access_control._default(); OSIMgmt::AttributeValueSeq attribute_id_list(1); attribute_id_list.length(1); ASN1_Choice oc_choice; oc_choice.selector = 0; oc_choice.value <<= (const char *)"emApplicationDatabase"; attribute_id_list[0].attribute_id = (const char *)"objectClass"; attribute_id_list[0].value <<= oc_choice; //**************************************************************** // STEP NO 4: Prepare reply handler //**************************************************************** CreateLinkedReplyHandlerImpl reply_handler; cout << "\ncreate_client: LinkedReplyHandler is ready\n" << flush; action_poa->activate_object(&reply_handler); CosNaming::Name ref_oi(0); // empty ref_oi.length(0); //**************************************************************************************** // STEP NO 5: Build the Managed Object name to be created //**************************************************************************************** osi_agent->cmis_create( interface_name, kind, object_name, access_control, ref_oi, attribute_id_list, reply_handler._this() ); poa_manager->activate(); orb->run(); } catch( const CORBA::Exception& e ) { cerr << "FAILED: caught exception " << endl; exit(1); } catch(...) { cerr << "FAILED: Unexpected exception " << endl; exit(1); } //************************************************************************************* // STEP NO 6: "release the Session" or destroy ProxyAgent //************************************************************************************* try { JIDM::Criteria_var return_criteria = proxy_agent->destroy(JIDM::ProxyAgent::gracefully, a_criteria ); if ((JIDM::Criteria*)NULL != return_criteria) { cout << "PASSED : Deleted Proxy Agent gracefully" << endl; } } catch(...) { cerr << "FAILED: Unable to delete Proxy Agent gracefully\n" << flush; exit(1); } return 0; }
Note <MIS-HOST> is passed as the third parameter to this test program. MIS-HOST is the host machine on which Solstice EM MIS is running, NAME-HOST is the host machine on which naming services is running and NAME-PORT is the TCP/IP port number on which the naming service on host <NAME-HOST> is listening for IIOP messages coming from client or manager applications.
The steps in this program are:
1. Initializing the ORB and object adapters; Resolving the naming services and getting the root naming context.
- Note that the SEM CORBA package provides a class called CGWGlobal which has static declarations for the ORB and POA attributes.
2. Getting the reference for ProxyAgentFinder.3. Building the key and criteria for getting access to the ProxyAgent which is implemented by the RGW (see Section2.2.1 Connecting Clients for the First Time).
- The key and criteria access parameters are critical for identifying the domain of the managed object (done by calling access_domain()).
- key consists of a key_id and a key_kind. The following key values are adopted by JIDM standards for key_id and key_kind.
- key_id:
- key_kind:
- criteria is the second parameter in the call access_domain() and contains the information needed to establish the session between the managed object domain and the manager. criteria has many components, but only domain title is identified as being required for all the Systems Management Reference Models.
- The following are the components of criteria:
- criteria_name:
- domain title of type CORBA::string
- controller object of type JIDM::ProxyAgentController
- user profile of type CORBA::Any
Note This list of criteria_name components is for general domain access and applies to both OSI and the Internet. There are some criteria_name parameters that are specific to the OSI management model. A complete list can be found in Appendix C.
Note In CODE EXAMPLE 3-2, criteria has two components -- domain title and user profile. domain title is the title associated with managed objects, and is defined for Solstice EM as "Solstice EM MIS".
- The value passed for user profile is the encrypted user profile. The user profile is encrypted by invoking the AuthenticationClientHandle::encrypt_user_profi le operation.
- The controller object lets manager applications control the destruction of ProxyAgents. The value passed in this case must be the reference of the JIDM::ProxyAgentController.
4. Getting the ProxyAgent reference for the key and criteria parameters.5. Creating a reply handler.
- The details of what the reply handler class does (CreateLinkedReplyHandlerImpl) is not shown in the example.
6. Deciding the name of the managed object to be created.7. Calling the OSImgmt::cmis_create method.
- The cmis_create() function requires the following input parameters:
- interface_name: The interface to be exported by the newly created object.
- creation_kind: The type of creation mechanism to be used; also identifies the use of the next parameter; the possible values are:
- simple: Create the object named in the following parameter.
- autonaming: Ignore the contents of the following parameter, and automatically assign a name for the newly created object.
- subordinate: The name specified in the next parameter is the name of the superior object under which the object is to be created.
- object_name: Specifies the IDL name of the managed object to be created (if creation_kind is simple) or the name of the superior object (if creation_kind is subordinate); if creation_kind is autonaming, the contents of this parameter are ignored.
- access_control: This parameter of type X711CMI::AccessControlTypeOpt is optional and contains information to be used as input to access control functions.
- reference_object: This parameter indicates the reference to a managed object needed to create the new object.
- req_attribute_values: Specifies a set of attribute values to be assigned at object creation time.
- LinkedReplyHandler: Interface implemented by the client or the application and a reference is passed. For more information see Section3.2.1 Operating Asynchronously and Synchronously.
- For synchronous operation using cmis_create_sync() refer to the IDL file, OSIMgmt.idl.
8. Releasing (terminating) the session by destroying the ProxyAgent.3.2.4 Deleting Objects
You can delete managed objects using the cmis_delete() function of the OSIMgmt::ProxyAgent interface. If you attempt to delete a non-existent object, it will result in a sub-tree error. For details see Section3.2.1 Operating Asynchronously and Synchronously.
cmis_delete() returns the following conditions to indicate errors:
- Operation Cancelled
- Access Denied
- Complexity Limitation
- Complexity Limitation Empty
- Invalid Scope
- No Such Object Class
- No Such Object Instance
- Processing Failure
- Processing Failure Empty
- Synchronous Not Supported
The following code example shows how to delete a managed object asynchronously
CODE EXAMPLE 3-3 Deleting Managed Objects Asynchronously
// Copyright 05/19/99 Sun Microsystems, Inc. All Rights Reserved. #pragma ident "@(#)delete_client.cc 1.1 99/05/19 Sun Microsystems" #include <unistd.h> #include <iostream.h> #ifdef ORBACUS #include <OB/CORBA.h> #include "CosNaming.h" #include "jidm/OSIMgmt.h" #include <jidm_ext/ASN1TypesExt_skel.h> #else #ifdef ORBIX #include <omg/orb.hh> #include "CosNaming.hh" #include "jidm/OSIMgmt.hh" #include <jidm_ext/ASN1TypesExtS.hh> #else #include "cos/CosNaming_c.hh" #include "jidm/OSIMgmt_c.hh" #include <jidm_ext/ASN1TypesExt_s.hh> #endif #endif #include "em_c++utils/dynamic_output_string_stream.hh" #include "em_c++utils/ts_shutdown_manager.hh" #include "corba_gateway_connection.hh" #include "delete_linked_reply_handler_impl.hh" int main( int argc, char **argv ) { if (argc < 4) { cout << "delete_client -SVCnameroot <Root Naming Context>" << " <MIS host name> [-ORBagentaddr <I/P address>/<host name>]\n" << flush; exit(1); } CORBA::ORB_var orb; PortableServer::POA_var root_poa; PortableServer::POA_var action_poa; PortableServer::POAManager_var poa_manager; TSShutdownManager& shutdown_mgr = TSShutdownManager::instance(); SampleShutdownCallback* sample_shutdown_cb = new SampleShutdownCallback(); shutdown_mgr.add_callback(sample_shutdown_cb); try { orb = CORBA::ORB_init(argc, argv); cout << "PASSED: Resolving RootPOA reference" << endl; root_poa = PortableServer::POA::_narrow(orb->resolve_initial_references("RootPOA")); if (CORBA::is_nil(root_poa)) { cout << "Unable to get RootPOA context!!" << endl; exit(1); } poa_manager = root_poa->the_POAManager(); // Create policies for our action POA CORBA::PolicyList policies; policies.length(1); policies[(CORBA::ULong)0] = root_poa->create_lifespan_policy(PortableServer::TRANSIENT); // Create the action servant and activate it on action_poa // Create action poa with our own policies action_poa = root_poa->create_POA("action_poa", NULL, policies); } catch(const CORBA::Exception& e) { cerr << "FAILED:Caught CORBA Exception " << endl; exit(1); } CORBAGatewayConnection cgw_connection( CORBA::ORB::_duplicate(orb)//, ); JIDM::ProxyAgentFinder_var proxy_agent_finder = cgw_connection.get_proxy_agent_finder(); JIDM::ProxyAgent_var proxy_agent; try { proxy_agent = cgw_connection.get_proxy_agent(); } catch ( const CORBA::Exception& e ) { cerr << "FAILED: Unable to obtain proxy agent:\n " << flush; } try { // beginning of preparing reply handler OSIMgmt::ProxyAgent_var osi_agent = OSIMgmt::ProxyAgent::_narrow(proxy_agent); // Issue cmis_delete() // construct oc const char* interface_name = (const char *)"log"; // construct oi DynamicOutputStringStream tmp_buf; tmp_buf << "systemId=name:'" << argv[3] << "'"; // mis host name CosNaming::Name object_name(3); object_name.length(3); object_name[0].id = (const char *)"root"; object_name[1].id = (const char *)tmp_buf.get_string(); object_name[2].id = (const char *)"logId=string:'AlarmLog'"; // construct scope X711CMI::ScopeType scope; scope.individualLevels(1); // NTH_LEVEL 1 // construct filter: // "item : equality : {objectClass, objectCreationRecord}" X711CMI::CMISFilterType filter; X711CMI::FilterItemType item_type; X711CMI::AttributeType val; val.attributeId.globalForm((const char *)"objectClass"); ASN1_Choice ac; ac.selector = 0; ac.value <<= (const char *)"objectCreationRecord"; val.attributeValue <<= ac; item_type.equality(val); filter.item(item_type); item_type.equality(val); filter.item(item_type); // construct sync X711CMI::CMISSyncType sync = X711CMI::bestEffort; // dummy access control X711CMI::AccessControlTypeOpt access_control; access_control._default(); DeleteLinkedReplyHandlerImpl reply_handler; // If want to test sync version of cmis_delete(), make // end_of_replies_handler to NULL. DeleteEndOfRepliesHandlerImpl end_of_replies_handler; cout << "\ndelete_client: LinkedReplyHandler is ready\n" << flush; action_poa->activate_object(&reply_handler); // If want to test sync version of cmis_delete(), // don't call obj_is_ready(end_of_replies_handler). action_poa->activate_object(&end_of_replies_handler); osi_agent->cmis_delete( interface_name, object_name, scope, filter, sync, access_control, reply_handler._this(), end_of_replies_handler._this() ); cout << "cmis_delete() returns " << endl; poa_manager->activate(); orb->run(); } catch( const CORBA::Exception& e ) { cerr << "FAILED: impl is interrupted" << endl; exit(1); } catch(...) { cerr << "FAILED: Unexpected exception " << endl; exit(1); } return 0; }3.2.5 Obtaining Object Attributes
You can obtain the value or the attribute of a managed object by calling the cmis_get() function of the OSIMgmt::ProxyAgent interface.
cmis_get() returns the following conditions to indicate errors:
- Get List Error
- Operation Cancelled
- Access Denied
- Complexity Limitation
- Complexity Limitation Empty
- Invalid Scope
- No Such Object Class
- No Such Object Instance
- Processing Failure
- Processing Failure Empty
- Synchronous Not Supported
- Duplication Invocation
- Mistyped Argument
- Resource Limitation
- Unrecognized Operation
The following code example shows how to get object attributes using cmis_get() asynchronously.
CODE EXAMPLE 3-4 Getting Object Attributes using cmis_get()
// Copyright 05/17/99 Sun Microsystems, Inc. All Rights Reserved. #pragma ident "@(#)get_client.cc 1.2 99/05/17 Sun Microsystems" #include <unistd.h> #include <iostream.h> #ifdef ORBACUS #include <OB/CORBA.h> #include "jidm/OSIMgmt.h" #include "jidm_ext/ASN1TypesExt_skel.h" #else #ifdef ORBIX #include <omg/orb.hh> #include "jidm/OSIMgmt.hh" #include "jidm_ext/ASN1TypesExtS.hh" #else #include "cos/CosNaming_c.hh" #include "jidm/OSIMgmt_c.hh" #include <jidm_ext/ASN1TypesExt_s.hh> #endif #endif #include <em_c++utils/dynamic_output_string_stream.hh> #include <em_c++utils/ts_shutdown_manager.hh> #include "corba_gateway_connection.hh" #include "get_linked_reply_handler_impl.hh" int main(int argc, char **argv) { if (argc < 4) { cout << "get_client -SVCnameroot <Root Naming Context> <MIS host name>" << " [-ORBagentaddr <I/P address>/<host name>]\n" << flush; exit(1); } PortableServer::POA_var root_poa; PortableServer::POA_var action_poa; PortableServer::POAManager_var poa_manager; TSShutdownManager& shutdown_mgr = TSShutdownManager::instance(); SampleShutdownCallback* sample_shutdown_cb = new SampleShutdownCallback(); shutdown_mgr.add_callback(sample_shutdown_cb); try { CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); cout << "PASSED: Resolving RootPOA reference" << endl; root_poa = PortableServer::POA::_narrow(orb->resolve_initial_references("RootPOA")); if (CORBA::is_nil(root_poa)) { cout << "Unable to get RootPOA context!!" << endl; exit(1); } poa_manager = root_poa->the_POAManager(); // Create policies for our action POA CORBA::PolicyList policies; policies.length(1); policies[(CORBA::ULong)0] = root_poa->create_lifespan_policy(PortableServer::TRANSIENT); // Create the action servant and activate it on action_poa // Create action poa with our own policies action_poa = root_poa->create_POA("action_poa", NULL, policies); cout << "Connecting to the CORBA Gateway ...\n" << flush; CORBAGatewayConnection cgw_connection( CORBA::ORB::_duplicate(orb)); JIDM::ProxyAgentFinder_var proxy_agent_finder = cgw_connection.get_proxy_agent_finder(); JIDM::ProxyAgent_var proxy_agent = cgw_connection.get_proxy_agent(); OSIMgmt::ProxyAgent_var osi_agent = OSIMgmt::ProxyAgent::_narrow(proxy_agent); // Issue cmis_get() // construct oc DynamicOutputStringStream tmp_buf; tmp_buf << "systemId=name:'" << "gemini" << "'"; // mis host name const char* interface_name = (const char *)"log"; // construct oi CosNaming::Name object_name(3); object_name.length(3); object_name[0].id = (const char *)"root"; object_name[1].id = (const char *)tmp_buf.get_string(); object_name[2].id = (const char *)"logId=string:'AlarmLog'"; // construct scope X711CMI::ScopeType scope; scope.individualLevels(0); // construct filter: "item : equality : {objectClass, log}" X711CMI::CMISFilterType filter; X711CMI::FilterItemType item_type; X711CMI::AttributeType val; val.attributeId.globalForm((const char *)"objectClass"); ASN1_Choice ach; ach.selector = 0; ach.value <<= (const char *)"log"; val.attributeValue <<= ach; item_type.equality(val); filter.item(item_type); // construct sync X711CMI::CMISSyncType sync = X711CMI::bestEffort; // dummy access control X711CMI::AccessControlTypeOpt access_control; access_control._default(); // construct attribute_id_list OSIMgmt::ASN1_ObjectIdentifierSeq attribute_id_list(0); attribute_id_list.length(0); #if 0 OSIMgmt::ASN1_ObjectIdentifierSeq attribute_id_list(1); attribute_id_list.length(1); attribute_id_list[0] = (const char *)"maxLogSize"; #endif GetLinkedReplyHandlerImpl reply_handler; GetEndOfRepliesHandlerImpl end_of_replies_handler; cout << "\nget_client: LinkedReplyHandler is ready\n" << flush; action_poa->activate_object(&reply_handler); action_poa->activate_object(&end_of_replies_handler); osi_agent->cmis_get( interface_name, object_name, scope, filter, sync, access_control, attribute_id_list, reply_handler._this(), end_of_replies_handler._this()); cout << "get_client has sent the M-Get request to CORBA Gateway\n" << flush; poa_manager->activate(); orb->run(); } catch(const CORBA::Exception& e) { cerr << "FAILED: \n " << endl; exit(1); } catch (...) { cerr << "FAILED: Unexpected exception caught\n"; exit(1); } return 0; }The following code example shows how to get object attributes using cmis_get_text asynchronously
.
CODE EXAMPLE 3-5 Getting Object Attributes using cmis_get_text()
// Copyright 06/01/99 Sun Microsystems, Inc. All Rights Reserved. #pragma ident "@(#)get_text_client.cc 1.1 99/06/01 Sun Microsystems" #include <unistd.h> #include <iostream.h> #ifdef ORBACUS #include <OB/CORBA.h> #include <jidm_ext/ASN1TypesExt_skel.h> #else #ifdef ORBIX #include <omg/orb.hh> #include <jidm_ext/ASN1TypesExtS.hh> #else #include <jidm_ext/ASN1TypesExt_s.hh> #endif #endif #include <em_c++utils/dynamic_output_string_stream.hh> #include <em_c++utils/ts_shutdown_manager.hh> #include "corba_gateway_connection.hh" #include "get_text_linked_reply_handler_impl.hh" // *********************************************************************** // Usage: // get_text_client -SVCnameroot <Root Naming Context> <MIS host name> // [-ORBagentaddr <I/P address>/<host name>] // // get_text_client sample program starts a connection with the CORBA Gateway, // obtains a proxy_agent // It sends a cmis get command to get the maxLogSize attribute value of the // alarmLog. // *********************************************************************** int main( int argc, char **argv ) { if (argc < 4) { cout << "get_text_client -SVCnameroot <Root Naming Context>" << " <MIS host name> [-ORBagentaddr <I/P address>/<host name>]\n" << flush; exit(1); } PortableServer::POA_var root_poa; PortableServer::POA_var action_poa; PortableServer::POAManager_var poa_manager; TSShutdownManager& shutdown_mgr = TSShutdownManager::instance(); SampleShutdownCallback* sample_shutdown_cb = new SampleShutdownCallback(); shutdown_mgr.add_callback(sample_shutdown_cb); try { CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); cout << "PASSED: Resolving RootPOA reference" << endl; root_poa = PortableServer::POA::_narrow(orb->resolve_initial_references("RootPOA")); if (CORBA::is_nil(root_poa)) { cout << "Unable to get RootPOA context!!" << endl; exit(1); } poa_manager = root_poa->the_POAManager(); // Create policies for our action POA CORBA::PolicyList policies; policies.length(1); policies[(CORBA::ULong)0] = root_poa->create_lifespan_policy(PortableServer::TRANSIENT); // Create the action servant and activate it on action_poa // Create action poa with our own policies action_poa = root_poa->create_POA("action_poa", NULL, policies); cout << "Connecting to the CORBA Gateway ...\n" << flush; CORBAGatewayConnection cgw_connection( CORBA::ORB::_duplicate(orb) ); JIDM::ProxyAgentFinder_var proxy_agent_finder = cgw_connection.get_proxy_agent_finder(); JIDM::ProxyAgent_var proxy_agent = cgw_connection.get_proxy_agent(); OSIMgmtExt::ProxyAgent_var osi_agent = OSIMgmtExt::ProxyAgent::_narrow(proxy_agent); // Issue cmis_get_text() // construct oc const char* interface_name = (const char *)"log"; // construct oi DynamicOutputStringStream object_name; object_name << "/systemId=name:'" << argv[3] << "'/logId=string:'AlarmLog'"; // construct scope X711CMI::ScopeType scope; scope.individualLevels(0); // construct filter: "item : equality : {objectClass, log}" CMIExt::CMISFilterType filter = CORBA::string_dup("and : { }"); X711CMI::CMISSyncType sync = X711CMI::bestEffort; // construct attribute_id_list OSIMgmt::ASN1_ObjectIdentifierSeq attribute_id_list(0); attribute_id_list.length(0); GetTextLinkedReplyHandlerImpl reply_handler; GetEndOfRepliesHandlerImpl end_of_replies_handler; cout << "get_text_client: LinkedReplyHandler is ready\n" << flush; action_poa->activate_object(&reply_handler); action_poa->activate_object(&end_of_replies_handler); cout << "BEFORE CMIS_GET_TEXT " << endl; osi_agent->cmis_get_text( interface_name, object_name.get_string(), scope, filter, sync, attribute_id_list, reply_handler._this(), end_of_replies_handler._this() ); cout << " AFTER CMIS_GET_TEXT " << endl; cout << "get_text_client has sent the M-Get(text) request to CORBA" << "Gateway\n" << flush; poa_manager->activate(); orb->run(); } catch(const CORBA::Exception& e) { cerr << "FAILED: \n " << endl; exit(1); } catch (...) { cerr << "FAILED: Unexpected exception caught\n"; exit(1); } return 0; }3.2.6 Obtaining Multiple Object Attributes
You can obtain multiple attributes from the RGW by specifying the scope and the filtering to be applied when calling the CMIS functions. You can also get multiple attributes by using attribute_id_list in a special way, as discussed later in this section. You can also define the interaction characteristics of selected objects (through scoping and filtering) by specifying synchronization and access control parameters.
3.2.6.1 Selecting Objects Through Scoping and Filtering
To specify the set of managed objects on which the operation is to be applied, select the appropriate integer value for the scope option:
- A value of 0 specifies the base object alone.
- A value of 1 specifies the first level only.
- A value of 2 specifies the whole subtree.
To specify the set of filtering tests to be performed on the set of managed objects (selected by applying scope) use the filter option. Group multiple tests together using combinations of AND, OR and NOT.
You can test for the following filter conditions:
- equality
- greater than or equal to
- less than or equal to
- presence
- subset of
- superset of
- non-Null intersection
- substring
If the managed object is not selected by the scope specified, the filter assertion test for that managed object evaluates to FALSE, and the managed object is not chosen for that operation; if no filter is specified, however, all of the managed objects included by the defined scope are selected for the operation.
3.2.6.2 Synchronization and Access Control
The synchronization parameter has two possible values, Best Effort and Atomic. Best Effort synchronization only requires that all the managed objects chosen (through filtering and scoping), be requested to perform the operation without any guarantee of a successful response. Atomic synchronization ensures that all the managed objects chosen (through scoping and filtering) are able to successfully perform the operation together--if one or more objects cannot perform the operation, then none of them are requested to perform it.
If only the base object is selected by the scope for the operation, the synchronization parameter is ignored.
The access control option specifies the functions to be used for access control. If this optional parameter (as specified in the JIDM standards) is not specified, the access control parameters specified at the time of ProxyAgent creation are used instead. At present the SEM CORBA Gateway implementation only supports access control through ProxyAgent.
3.2.6.3 attribute_id_list parameters
You can use the attribute_id_list parameters available for some CMIS operations (such as get) to enable clients to implement scope operations. This list is a sequence of ASN1_ObjectIdentifiers of the managed objects on which the operation is to be carried out. If this list is empty, all the managed objects under the current base object will be fetched.
The following code segment shows how to use a get operation to read all the attributes under "systemId=name:faith/logId=string:AlarmLog".
CODE EXAMPLE 3-6 Obtaining Multiple Object Attributes
CosNaming::Name object_name(3); object_name.length(3); object_name[0].id = (const char *)"root"; tmp_buf << "systemId=name:'" << "faith" << "'"; object_name[1].id = (const char *)tmp_buf.get_string(); object_name[2].id = (const char *)"logId=string:'AlarmLog'"; // construct scope X711CMI::ScopeType scope; // Whole substree scope.level(2); X711CMI::CMISFilterType filter; X711CMI::FilterItemType item_type; X711CMI::AttributeType val; // Construct a null filter _and_seq filter_seq(0); filter_seq.length(0); filter._cxx_and(filter_seq); // construct sync X711CMI::CMISSyncType sync = X711CMI::bestEffort; // dummy access control X711CMI::AccessControlTypeOpt access_control; access_control._default(); // construct attribute_id_list // We want to get all the attributes under the subtree, so set att list = 0 OSIMgmt::ASN1_ObjectIdentifierSeq attribute_id_list(0); attribute_id_list.length(0); // Rest of the code is not shown in this code segment3.2.7 Modifying Object Attributes
You can modify or set the managed object attributes using the cmis_set() function exposed by OSIMgmt::ProxyAgent interface. CODE EXAMPLE 3-7 shows how to set or modify attributes of an object.
cmis_set() returns the following conditions to indicate errors:
- Operation Cancelled
- Access Denied
- Complexity Limitation
- Complexity Limitation Empty
- Invalid Scope
- No Such Object Class
- No Such Object Instance
- Processing Failure
- Processing Failure Empty
- Synchronous Not Supported
- Set List Error
CODE EXAMPLE 3-7 Modifying Object Attributes
// Copyright 05/17/99 Sun Microsystems, Inc. All Rights Reserved. #pragma ident "@(#)set_client.cc 1.1 99/05/17 Sun Microsystems" #include <unistd.h> #include <iostream.h> #ifdef ORBACUS #include <OB/CORBA.h> #include "CosNaming.h" #include "jidm/OSIMgmt.h" #include "jidm_ext/ASN1TypesExt_skel.h" #else #ifdef ORBIX #include <omg/orb.hh> #include "CosNaming.hh" #include "jidm/OSIMgmt.hh" #include "jidm_ext/ASN1TypesExtS.hh" #else #include "cos/CosNaming_c.hh" #include "jidm/OSIMgmt_c.hh" #include <jidm_ext/ASN1TypesExt_s.hh> #endif #endif #include <em_c++utils/dynamic_output_string_stream.hh> #include <em_c++utils/ts_shutdown_manager.hh> #include "corba_gateway_connection.hh" #include "set_linked_reply_handler_impl.hh" int main( int argc, char **argv ) { if (argc < 4) { cout << "get_client -SVCnameroot <Root Naming Context> <MIS host name>" << " [-ORBagentaddr <I/P address>/<host name>]\n" << flush; exit(1); } CORBA::ORB_var orb; PortableServer::POA_var root_poa; PortableServer::POA_var action_poa; PortableServer::POAManager_var poa_manager; TSShutdownManager& shutdown_mgr = TSShutdownManager::instance(); SampleShutdownCallback* sample_shutdown_cb = new SampleShutdownCallback(); shutdown_mgr.add_callback(sample_shutdown_cb); try { orb = CORBA::ORB_init(argc, argv); cout << "PASSED: Resolving RootPOA reference" << endl; root_poa = PortableServer::POA::_narrow(orb->resolve_initial_references("RootPOA")); if (CORBA::is_nil(root_poa)) { cout << "Unable to get RootPOA context!!" << endl; exit(1); } poa_manager = root_poa->the_POAManager(); // Create policies for our action POA CORBA::PolicyList policies; policies.length(1); policies[(CORBA::ULong)0] = root_poa->create_lifespan_policy(PortableServer::TRANSIENT); // Create the action servant and activate it on action_poa // Create action poa with our own policies action_poa = root_poa->create_POA("action_poa", NULL, policies); } catch(const CORBA::Exception& e) { cerr << "FAILED: " << endl; exit(1); } CORBAGatewayConnection cgw_connection( CORBA::ORB::_duplicate(orb)//, ); JIDM::ProxyAgentFinder_var proxy_agent_finder; JIDM::ProxyAgent_var proxy_agent; try { proxy_agent_finder = cgw_connection.get_proxy_agent_finder(); proxy_agent = cgw_connection.get_proxy_agent(); } catch ( const CORBA::Exception& e ) { cerr << "FAILED: Unable to obtain proxy agent:\n " << flush; } try { // beginning of preparing reply handler OSIMgmt::ProxyAgent_var osi_agent = OSIMgmt::ProxyAgent::_narrow(proxy_agent); // construct oc DynamicOutputStringStream tmp_buf; tmp_buf << "systemId=name:'" << argv[3] << "'"; // mis host name const char* interface_name = (const char *)"log"; // construct oi CosNaming::Name object_name(3); object_name.length(3); object_name[0].id = (const char *)"root"; object_name[1].id = (const char *)tmp_buf.get_string(); object_name[2].id = (const char *)"logId=string:'AlarmLog'"; // construct scope X711CMI::ScopeType scope; scope.individualLevels(0); // // construct filter: "item : equality : {objectClass, log}" // X711CMI::CMISFilterType filter; X711CMI::FilterItemType item_type; X711CMI::AttributeType val; val.attributeId.globalForm((const char *)"objectClass"); ASN1_Choice ach; ach.selector = 0; ach.value <<= (const char *)"log"; val.attributeValue <<= ach; item_type.equality(val); filter.item(item_type); // construct sync X711CMI::CMISSyncType sync = X711CMI::bestEffort; // dummy access control X711CMI::AccessControlTypeOpt access_control; access_control._default(); // construct modify_list OSIMgmt::SetOperationArgument modify_list(1); modify_list.length(1); modify_list[0].modify_operator = OSIMgmt::replace; modify_list[0].attribute_id = (const char*)"maxLogSize"; modify_list[0].attribute_value <<= (CORBA::Long)900000; SetLinkedReplyHandlerImpl reply_handler; SetEndOfRepliesHandlerImpl end_of_replies_handler; action_poa->activate_object(&reply_handler); action_poa->activate_object(&end_of_replies_handler); cout << "\nset_client: LinkedReplyHandler is ready\n" << flush; osi_agent->cmis_set( interface_name, object_name, scope, filter, sync, access_control, modify_list, reply_handler._this(), end_of_replies_handler._this() ); cout << "set_client has sent the M-Set request to CORBA Gateway\n" << flush; poa_manager->activate(); orb->run(); } catch(const CORBA::Exception& e) { cerr << "FAILED: Unexpected CORBA Exception" << endl; exit(1); } }3.2.8 Performing an Operation on a Managed Object
You can use the cmis_action() function of the OSIMgmt::ProxyAgent interface to perform a certain action on a managed object and indicate the result of the action back to the client.
cmis_action() returns the following conditions to indicate errors:
- Operation Cancelled
- Access Denied
- Complexity Limitation
- Complexity Limitation Empty
- Invalid Scope
- No Such Object Class
- No Such Object Instance
- Processing Failure
- Processing Failure Empty
- Synchronous Not Supported
- Invalid Argument Value
- No Such Action
- No Such Argument
The following code example shows how to perform an operation on a managed object.
CODE EXAMPLE 3-8 Performing an Operation on a Managed Object
// Copyright 05/25/99 Sun Microsystems, Inc. All Rights Reserved. #pragma ident "@(#)action_client.cc 1.1 99/05/25 Sun Microsystems" #include <unistd.h> #include <iostream.h> #ifdef ORBACUS #include <OB/CORBA.h> #include <CosNaming.h> #include <jidm/OSIMgmt.h> #include "jidm/X711CMI.h" #include <jidm_ext/ASN1TypesExt_skel.h> #else #ifdef ORBIX #include <omg/orb.hh> #include <CosNaming.hh> #include <jidm/OSIMgmt.hh> #include "jidm/X711CMI.hh" #include <jidm_ext/ASN1TypesExtS.hh> #else #include <cos/CosNaming_c.hh> #include <jidm/OSIMgmt_c.hh> #include "jidm/X711CMI_c.hh" #include <jidm_ext/ASN1TypesExt_s.hh> #endif #endif #include <em_c++utils/dynamic_output_string_stream.hh> #include <em_c++utils/ts_shutdown_manager.hh> #include "corba_gateway_connection.hh" #include "action_linked_reply_handler_impl.hh" int main( int argc, char **argv ) { if (argc < 5) { cout << "action_client -SVCnameroot <Root Naming Context>" << " <MIS host name> <Device Name>" << " [-ORBagentaddr <I/P address>/<host name>]\n" << flush; exit(1); } CORBA::ORB_var orb; PortableServer::POA_var root_poa; PortableServer::POA_var action_poa; PortableServer::POAManager_var poa_manager; TSShutdownManager& shutdown_mgr = TSShutdownManager::instance(); SampleShutdownCallback* sample_shutdown_cb = new SampleShutdownCallback(); shutdown_mgr.add_callback(sample_shutdown_cb); try { orb = CORBA::ORB_init(argc, argv); cout << "PASSED: Resolving RootPOA reference" << endl; root_poa = PortableServer::POA::_narrow(orb->resolve_initial_references("RootPOA")); if (CORBA::is_nil(root_poa)) { cout << "Unable to get RootPOA context!!" << endl; exit(1); } poa_manager = root_poa->the_POAManager(); // Create policies for our action POA CORBA::PolicyList policies; policies.length(1); policies[(CORBA::ULong)0] = root_poa->create_lifespan_policy(PortableServer::TRANSIENT); // Create the action servant and activate it on action_poa // Create action poa with our own policies action_poa = root_poa->create_POA("action_poa", NULL, policies); } catch( const CORBA::Exception& e ) { cerr << "FAILED: Caught CORBA Exception " << endl; exit(1); } CORBAGatewayConnection cgw_connection( CORBA::ORB::_duplicate(orb) ); JIDM::ProxyAgentFinder_var proxy_agent_finder; JIDM::ProxyAgent_var proxy_agent; try { proxy_agent_finder = cgw_connection.get_proxy_agent_finder(); proxy_agent = cgw_connection.get_proxy_agent(); } catch ( const CORBA::Exception& e ) { cerr << "FAILED: Unable to obtain proxy agent:\n" << flush; } try { // beginning of preparing reply handler OSIMgmt::ProxyAgent_var osi_agent = OSIMgmt::ProxyAgent::_narrow(proxy_agent); // Issue cmis_action() // construct oc const char* interface_name = (const char *)"topoNodeDB"; // construct oi DynamicOutputStringStream mis_host_name; mis_host_name << "systemId=name:'" << argv[3] << "'"; CosNaming::Name object_name(3); object_name.length(3); object_name[0].id = (const char *)"root"; object_name[1].id = (const char *)mis_host_name.get_string(); object_name[2].id = (const char *)"topoNodeDBId=NULL"; // construct scope X711CMI::ScopeType scope; scope.level(0); // BASE_OBJECT // construct filter: default X711CMI::CMISFilterType filter; //_and_seq filter_seq(0); //filter_seq.length(0); //filter._cxx_and(filter_seq); // construct sync X711CMI::CMISSyncType sync = X711CMI::bestEffort; // dummy access control X711CMI::AccessControlTypeOpt access_control; access_control._default(); // construct action name - topoNodeGetByName ASN1_ObjectIdentifier action_name = CORBA::string_dup("topoNodeGetByName"); cout << "Device Type: " << argv[4] << endl; // construct action info ASN1_DefinedAny action_info; action_info <<= (const char*)argv[4]; ActionLinkedReplyHandlerImpl reply_handler; ActionEndOfRepliesHandlerImpl end_of_replies_handler; action_poa->activate_object(&reply_handler); action_poa->activate_object(&end_of_replies_handler); cout << "\n action_client: LinkedReplyHandler is ready\n" << flush; osi_agent->cmis_action( interface_name, object_name, scope, filter, sync, access_control, action_name, action_info, reply_handler._this(), end_of_replies_handler._this() ); poa_manager->activate(); orb->run(); } catch( const CORBA::Exception& e ) { cerr << "FAILED: Unexpected CORBA Exception" << endl; exit(1); } }3.2.9 Cancelling a Request
To cancel a request that has already been sent, delete or deactivate the LinkedReplyHandler interface before the reply is received. The SEM CORBA Gateway that is processing the request will only send a reply if the LinkedReplyHandler interface still exists. If the LinkedReplyHandler interface does not exist, the gateway assumes that the request has been cancelled.
The following code example shows how to cancel a request that has already been sent.
CODE EXAMPLE 3-9 Cancelling a Request
// Copyright 06/01/99 Sun Microsystems, Inc. All Rights Reserved. #pragma ident "@(#)cancel_get_client.cc 1.2 99/06/01 Sun Microsystems" #include <unistd.h> #include <iostream.h> #ifdef ORBACUS #include <OB/CORBA.h> #include "jidm/OSIMgmt.h" #include <jidm_ext/ASN1TypesExt_skel.h> #else #ifdef ORBIX #include <omg/orb.hh> #include "jidm/OSIMgmt.hh" #include <jidm_ext/ASN1TypesExtS.hh> #else #include "jidm/OSIMgmt_c.hh" #include <jidm_ext/ASN1TypesExt_s.hh> #endif #endif #include <pthread.h> #include <em_c++utils/dynamic_output_string_stream.hh> #include <em_c++utils/ts_shutdown_manager.hh> #include "corba_gateway_connection.hh" #include "cancel_get_linked_reply_handler_impl.hh" CORBA::ORB_var orb; PortableServer::POA_var root_poa; PortableServer::POA_var action_poa; PortableServer::POAManager_var poa_manager; PortableServer::ObjectId_var oid; PortableServer::ObjectId_var oid1; void* deactivate_reply_handler( void* ) { cout << "Cancelling get request...\n" << flush; action_poa->deactivate_object(oid); //action_poa->deactivate_object(oid1); return NULL; } int main( int argc, char **argv ) { if (argc < 4) { cout << "cancel_get_client -SVCnameroot <Root Naming Context>" << " <MIS host name> [-ORBagentaddr <I/P address>/<host name>]\n" << flush; exit(1); } /* PortableServer::POA_var root_poa; PortableServer::POA_var action_poa; PortableServer::POAManager_var poa_manager; */ TSShutdownManager& shutdown_mgr = TSShutdownManager::instance(); SampleShutdownCallback* sample_shutdown_cb = new SampleShutdownCallback(); shutdown_mgr.add_callback(sample_shutdown_cb); try { orb = CORBA::ORB_init(argc, argv); cout << "PASSED: Resolving RootPOA reference" << endl; root_poa = PortableServer::POA::_narrow(orb->resolve_initial_references("RootPOA")); if (CORBA::is_nil(root_poa)) { cout << "Unable to get RootPOA context!!" << endl; exit(1); } poa_manager = root_poa->the_POAManager(); // Create policies for our action POA CORBA::PolicyList policies; policies.length(1); policies[(CORBA::ULong)0] = root_poa->create_lifespan_policy(PortableServer::TRANSIENT); // Create the action servant and activate it on action_poa // Create action poa with our own policies action_poa = root_poa->create_POA("action_poa", NULL, policies); } catch(const CORBA::Exception& e) { cerr << "FAILED: Caught CORBA Exception " << endl; exit(1); } CORBAGatewayConnection cgw_connection( CORBA::ORB::_duplicate(orb)//, ); JIDM::ProxyAgentFinder_var proxy_agent_finder; JIDM::ProxyAgent_var proxy_agent; try { proxy_agent_finder = cgw_connection.get_proxy_agent_finder(); proxy_agent = cgw_connection.get_proxy_agent(); } catch ( const CORBA::Exception& e ) { cerr << "FAILED: Unable to obtain proxy agent:\n " << flush; } try { // beginning of preparing reply handler OSIMgmt::ProxyAgent_var osi_agent = OSIMgmt::ProxyAgent::_narrow(proxy_agent); // construct oc const char* interface_name = (const char *)"log"; // construct oi DynamicOutputStringStream tmp_buf; CosNaming::Name object_name(3); object_name.length(3); object_name[0].id = (const char *)"root"; tmp_buf << "systemId=name:'" << argv[3] << "'"; object_name[1].id = (const char *)tmp_buf.get_string(); object_name[2].id = (const char *)"logId=string:'AlarmLog'"; // construct scope X711CMI::ScopeType scope; scope.individualLevels(1); // // construct filter: // "item : equality : {objectClass, nerveCenterAlarmRecord}" // X711CMI::CMISFilterType filter; X711CMI::FilterItemType item_type; X711CMI::AttributeType val; val.attributeId.globalForm((const char *)"objectClass"); ASN1_Choice ach; ach.selector = 0; ach.value <<= (const char *)"emAlarmRecord"; val.attributeValue <<= ach; item_type.equality(val); filter.item(item_type); // construct sync X711CMI::CMISSyncType sync = X711CMI::bestEffort; // dummy access control X711CMI::AccessControlTypeOpt access_control; access_control._default(); // construct attribute_id_list OSIMgmt::ASN1_ObjectIdentifierSeq attribute_id_list(1); attribute_id_list.length(1); attribute_id_list[0] = (const char *)"logRecordId"; GetLinkedReplyHandlerImpl reply_handler; GetEndOfRepliesHandlerImpl end_of_replies_handler; oid = action_poa->activate_object(&reply_handler); oid1 = action_poa->activate_object(&end_of_replies_handler); cout << "\ncancel_get_client: LinkedReplyHandler is ready\n" << flush; osi_agent->cmis_get( interface_name, object_name, scope, filter, sync, access_control, attribute_id_list, reply_handler._this(), end_of_replies_handler._this() ); cout << "cancel_get_client has sent the M-Get request to CORBA Gateway" << endl << flush; pthread_t tid; if(pthread_create(&tid, NULL, deactivate_reply_handler, NULL)) { cerr << "FAILED: unable to start deactivate_reply_handler\n" << flush; } poa_manager->activate(); orb->run(); } catch(const CORBA::Exception& e) { cerr << "FAILED: Unexpected CORBA Exception" << endl; exit(1); } }3.2.10 Subscribing to an Event
Applications that collect events need to subscribe to events as shown in CODE EXAMPLE 3-10. The SEM CORBA Gateway provides an OSIMgmt Extended ProxyAgent (OSIMgmtExt::ProxyAgent) that includes the functions subscribe_events() and unsubscribe_events().
subscribe_events() creates Event Forwarding Discriminators (EFDs) using cmis_create_text, and returns the subscription Id.
subscribe_events() returns the following conditions to indicate errors:
- Access Denied
- Processing Failure
unsubscribe_events() deletes the EFDs (using cmis_delete_text) and returns the following conditions to indicate errors:
- Access Denied
- Processing Failure
- Invalid Subscription
A pictorial representation of the steps involved in subscribing to an event is given in the following figure.
FIGURE 3-3 Subscribing to an Event
CODE EXAMPLE 3-10 Subscribing to an Event
// Copyright 06/01/99 Sun Microsystems, Inc. All Rights Reserved. #pragma ident "@(#)subscribe_events.cc 1.2 99/06/01 Sun Microsystems" #include <unistd.h> #include <iostream.h> #include <cos/CosNaming_c.hh> #include <jidm_ext/OSIMgmtExt_c.hh> #include <auth_helper/auth_client_handle.hh> #include <corba_utils/corba_utils.hh> #include <jidm_ext/ASN1TypesExt_c.hh> #include <em_c++utils/dynamic_output_string_stream.hh> /******************************************************* How to run this test program: ---------------------------- subscribe_events -a <ae_title> -SVCnameroot Quake *******************************************************/ int main( int argc, char **argv ) { CORBA::ORB_var orb; if (argc < 5) { cout << argv[0] << " -SVCnameroot Quake -a <ae_title>\n"; exit(1); } int c; extern int optind; extern char* optarg; const char* ae_title; while ((c = getopt(argc, argv, "a:S:")) != EOF) { switch (c) { case 'a': ae_title = CORBA::string_dup(optarg); break; case 'S': break; case '?': default: cerr << "Usage: " << argv[0] << " -a <OID-AE-title> -SVCnameroot <default root naming context>" << endl; return 1; } } try { orb = CORBA::ORB_init(argc, argv); } catch(const CORBA::Exception& e) { cerr << "FAILED: to initialize the ORB" << e; exit(1); } cout << "PASSED: ORB initialization\n" << flush; CosNaming::NamingContext_var root_nc; try{ CORBA::Object_var object = orb->resolve_initial_references("NameService"); root_nc = CosNaming::NamingContext::_narrow(object); if(CORBA::is_nil(root_nc)) { cerr << "FAILED: Unable to obtain root naming context\n" << flush; exit(2); } } catch(const CORBA::Exception& e) { cerr << "FAILED: Unable to obtain root naming context:\n " << e; exit(3); } cout << "PASSED: Obtained root naming context\n" << flush; CosNaming::Name name; name.length(1); JIDM::ProxyAgentFinder_var proxy_agent_finder; try{ name[0].id = CORBA::string_dup("JIDM::ProxyAgentFinder"); name[0].kind = CORBA::string_dup(""); CORBA::Object_var object = root_nc->resolve(name); proxy_agent_finder = JIDM::ProxyAgentFinder::_narrow(object); if (CORBA::is_nil(proxy_agent_finder)) { cerr << "FAILED: Unable to obtain correct Proxy Agent Finder\n" << flush; exit(4); } if(proxy_agent_finder->_non_existent()) { cerr << "FAILED: Proxy Agent Finder does not exist\n" << flush; exit(5); } } catch(const CORBA::Exception& e) { cerr << "FAILED: Unable to resolve JIDM::ProxyAgentFinder:\n " << e; exit(6); } cout << "PASSED: Obtained JIDM::ProxyAgentFinder reference\n" << flush; JIDM::Key a_key; a_key.length(1); a_key[0].id = CORBA::string_dup("OSI Management"); a_key[0].kind = CORBA::string_dup("XSM environment"); JIDM::Criteria a_criteria; a_criteria.length(2); a_criteria[0].name = CORBA::string_dup("domain title"); a_criteria[0].value <<= (const char*)ae_title; cout << "Enter User Name: " << flush; char user_name[128]; cin >> user_name; const char* password_prompt = "Enter Password: "; // getpassphrase return a pointer to static data which should not be // deleted char* raw_password = getpassphrase(password_prompt); AuthenticationClient* ac = new AuthenticationClientHandle("NBS_DES"); a_criteria[1].name = CORBA::string_dup("user_profile"); a_criteria[1].value = *(ac->encrypt_user_profile( user_name, raw_password, NULL)); // This will ensure that pass won't retain the raw password if process // dumps core memset(raw_password, 0x0c, sizeof(raw_password)); delete ac; if(a_criteria[1].value.type()->kind() == CORBA::tk_null) { cerr << "FAILED: Unable to obtain encrypted user profile\n" << flush; exit(1); } cout << "PASSED: Obtained criteria from encrypting user profile\n" << flush; JIDM::ProxyAgent_var proxy_agent; try { cout << flush; proxy_agent = proxy_agent_finder->access_domain(a_key, a_criteria); if (CORBA::is_nil(proxy_agent)) { cerr << "FAILED: Unable to obtain correct Proxy Agent" << endl << flush; throw 0; } if(proxy_agent->_non_existent()) { cerr << "FAILED: Proxy Agent does not exist" << endl << flush; throw 0; } } catch(const CORBA::UserException& e) { cerr << "FAILED: to get proxy_agent\n" << e << endl; exit(1); } catch( const CORBA::Exception& e ) { cerr << "FAILED: Unexcepted exception when trying to get proxy_agent\n"; exit(1); } cout << "PASSED: Created a new Proxy Agent\n" << flush; OSIMgmtExt::ProxyAgent_var osi_agent= OSIMgmtExt::ProxyAgent::_narrow(proxy_agent); StringSeq event_list; #if 0 // For all events: equivalent to and :{} event_list.length(0); #endif event_list.length(3); event_list[0] = CORBA::string_dup( "'Rec. X.721 | ISO/IEC 10165-2 : 1992': objectCreation"); event_list[1] = CORBA::string_dup( "'Rec. X.721 | ISO/IEC 10165-2 : 1992': objectDeletion"); event_list[2] = CORBA::string_dup( "'Rec. X.721 | ISO/IEC 10165-2 : 1992': attributeValueChange"); StringSeq object_class_list; object_class_list.length(0); StringSeq object_name_list; object_name_list.length(0); OSIMgmtExt::ProxyAgent::SubscriptionId_var sid; try { sid = osi_agent->subscribe_events( event_list, object_class_list, object_name_list ); cout << "Subscription ID = " << sid << endl; cout << endl << " ++++++++++++++++++++++++++++++" << endl; } catch (const CORBA::Exception& e) { cout << "subscribe_events() failed: " << e << endl; return 1; } cout << "Hit return to continue\n"; char reply[3]; cin >> reply; cout << "Now trying to unsubsribe for events...\n" << flush; osi_agent->unsubscribe_events(sid); cout << "Unsubsribed the previously subscribed event\n"; try { JIDM::Criteria_var return_criteria = proxy_agent->destroy( JIDM::ProxyAgent::gracefully, a_criteria ); if ((JIDM::Criteria*)NULL != return_criteria) { cout << "PASSED : Deleted Proxy Agent gracefully" << endl; } } catch(...) { cerr << "FAILED: Unable to delete Proxy Agent gracefully\n" << flush; exit(1); } return 0; }
Sun Microsystems, Inc. Copyright information. All rights reserved. |
Doc Set | Contents | Previous | Next | Index |