[Enterprise Extensions only]
  Previous topic

Creating CORBA server main code (server.cpp), adding code to access naming contexts

Use this task to add a "get name context" method (for example, called get_name_context) to the source file for a CORBA server, to access naming contexts. This method is used to create a new naming context within which the CORBA server can create and make available servant objects. The method performs the following actions after the server environment has been initialized:

  1. Getting a pointer to the naming service.
  2. Getting a pointer to the root naming context.
  3. (Optional) Creating a ::CosNaming::Name for the domain and getting a pointer to the domain naming context.
  4. Getting a new servant naming context for servant objects.

This task is one step of the parent task to create the CORBA server main code, as described in Creating a CORBA server main code (server.cpp).

To add a get_name_context() method to the source file for a CORBA server main code, edit the server source file, servantServer.cpp, and add the following code:

  1. Add a get_name_context() method, and add a statement to the main method to call the new method, as shown in the following code extract:
    // This function accesses the Name Service and then gets or creates
    // the desired naming contexts. It returns the naming context for
    // the servant context.
    
    ::CosNaming::NamingContext_var get_naming_context() 
    {
      ::CosNaming::NamingContext_var rootNameContext = NULL;
      ::CosNaming::NamingContext_var domainNameContext = NULL;
      ::CosNaming::NamingContext_var servantNameContext = NULL;
      ::CORBA::Object_ptr objPtr;
    
    
      return( servantNameContext );
    }
    
    ...
    
    void main( int argc, char *argv[] )
    {
    ...
    
      if ( ( rc = perform_initialization( argc, argv ) ) != 0 )
        exit( rc );
    
      // Get the various naming contexts.
     
      ::CosNaming::NamingContext_var servantNameContext = NULL;
      servantNameContext = get_naming_context();
     
      if ( ::CORBA::is_nil( servantNameContext ) )
        exit( -1 );
    ...
    } 
    

    Where:

    rootNameContext
    is the pointer to the root naming context.
    domainNameContext
    is the pointer to the (optional) domain naming context.
    servantNameContext
    is the pointer to the naming context for servant objects.

  2. Edit the get_name_context() method, to add code to get a pointer to the naming service, as shown in the following code extract:
    // This function accesses the Name Service and then gets or creates
    // the desired naming contexts. It returns the naming context for
    // the servant context.
    
    ::CosNaming::NamingContext_var get_naming_context() 
    {
      ::CosNaming::NamingContext_var rootNameContext = NULL;
      ::CosNaming::NamingContext_var domainNameContext = NULL;
      ::CosNaming::NamingContext_var servantNameContext = NULL;
      ::CORBA::Object_ptr objPtr;
    
      // Get access to the Naming Service.
      try
      {
    
        objPtr = op->resolve_initial_references( "NameService" );
    
      }
    
      // catch exceptions ...
    ...
    
      return( servantNameContext );
    }

    This step returns a pointer object, objPtr, to the naming service.

  3. Edit the get_name_context() method, to add code to get a pointer to the root naming context, as shown in the following code extract:
    ::CosNaming::NamingContext_var get_naming_context() 
    {
    ...
      else
        cout << "resolve_initial_references returned = " << objPtr << endl;
    
      // Get a root naming context.
    
      rootNameContext = ::CosNaming::NamingContext::_narrow(objPtr);
    
      if ( ::CORBA::is_nil( rootNameContext ) )
      {
        cerr << "ERROR: rootNameContext narrowed to nil" << endl;
        release_resources( bp, imp, op );
        return( NULL );
      }
      else
        cout << "rootNameContext = " << rootNameContext << endl;
      // Release the temporary pointer.
      ::CORBA::release(objPtr);
    
    ...
    } 
    

    This code narrows the pointer object to the appropriate object type and assigns it to the new pointer object called rootNameContext, performs some checks, then releases the original pointer object, objPtr.

    This step returns a pointer object, rootNameContext, to the root naming context.

  4. Edit the get_name_context() method, to add code to create a ::CosNaming::Name for the domain and get a pointer to the domain naming context, as shown in the following code extract:
    ::CosNaming::NamingContext_var get_naming_context() 
    {
    ...
      // Get a root naming context.
    ...
      // Release the temporary pointer.
      ::CORBA::release(objPtr);
    
      // Create a ::CosNaming::Name for the domain.
    
      ::CosNaming::NameComponent nc;
      nc.kind = CORBA::string_dup("");
      nc.id = CORBA::string_dup("domain");
      ::CosNaming::Name_var name = new ::CosNaming::Name( 1, 1, &nc, 0 );
      // Get the domain naming context.
      try
      {
        objPtr = rootNameContext->resolve( name );
    
        cout << "objPtr from nameContext resolve = " << objPtr << endl;
      }
    
      // catch exceptions ...
    
      cout << "Resolved domain in root name context" << endl;
    
    
      domainNameContext = ::CosNaming::NamingContext::_narrow(objPtr);
    
      if ( ::CORBA::is_nil( domainNameContext ) )
      {
        cerr << "ERROR: domainNameContext narrowed to null" << endl;
        release_resources( bp, imp, op );
        return( NULL );
      }
      cout << "domainNameContext = " << domainNameContext << endl;
      // Release the temporary pointer.
      ::CORBA::release( objPtr );
    
    ...
    } 
    

    The ::CosNaming::Name is initialized with the string "domain", which is the name of the domain naming context in which a new servant naming context is to be created. The domain naming context is located within the root naming context, so the root naming context is asked to resolve the name "domain". After resolving the name, the code narrows the result to get the domain naming context, assigns it to the new pointer object called domainNameContext, performs some checks, then releases the original pointer object, objPtr.

    This step returns a pointer object, domainNameContext, to the domain naming context.

  5. Edit the get_name_context() method, to add code to create a ::CosNaming::Name that specifies the name of the new context, "servantContext" (into which servant object are placed) and get a pointer to the naming context, as shown in the following code extract:
    ::CosNaming::NamingContext_var get_naming_context()
    {
    ...
      // Create a ::CosNaming::Name for the domain.
    ...
      // Release the temporary pointer.
      ::CORBA::release( objPtr );
    
      // Get a new naming context for our objects.
    
      ::CosNaming::NameComponent nc2;
      nc2.kind = CORBA::string_dup("");
      nc2.id = CORBA::string_dup("servantContext");
      ::CosNaming::Name_var name2 = new ::CosNaming::Name( 1, 1, &nc2, 0 );
      try
      {
        servantNameContext = domainNameContext->bind_new_context( name2 );
    
        cout << "bind_new_context, servantNameContext = " << objectNameContext
          << endl;
      }
    
      // catch exceptions ...
    
      catch( ::CosNaming::NamingContext::AlreadyBound e )
      {
        cerr << "ERROR: bind_new_context threw AlreadyBound" << endl;
        cout << "Trying to resolve the context" << endl;
        try
        {
    
          ::CosNaming::Name *servantName = new ::CosNaming::Name;
          servantName->length( 1 );
          (*servantName)[0].id = ::CORBA::string_dup( "servantContext" );
          (*servantName)[0].kind = ::CORBA::string_dup( "" );
          ::CORBA::Object_ptr objPtr = domainNameContext->resolve( *servantName );
    cout << "Before objectNameContext = " << servantNameContext << endl;
          servantNameContext = ::CosNaming::NamingContext::_narrow( objPtr );
    
    cout << "After servantNameContext = " << servantNameContext << endl;
        }
    
        // catch exceptions ...
    
      }
    
      return( servantNameContext );
    }
    
    ...
    }
    

    Where:

    servant
    is a string related to the name of the servant object class; for example, for the servant object class WSLogger you might create a naming context pointer called loggerNameContext.

    This code narrows the pointer object to the appropriate object type and assigns it to the new pointer object called , servantNameContext performs some checks, then releases the original pointer object, objPtr.

    This step returns a pointer object, servantNameContext, to the naming context for servant objects.

This task creates and returns a pointer object, servantNameContext, to the naming context for servant objects.

You need to add code to the server source file to name, create, and bind servant objects, as described in Creating CORBA server main code (server.cpp), adding code to name, create, and bind servant objects.

  Previous topic