NameResolve client & server

Example 32. name-resolve.idl

module Examples {
  module NameResolve {
    interface Service {
      void echoString (in string input);
    };
  };
};
$ orbit-idl-2 --skeleton-impl name-resolve.idl geenrates all the files we will use in this example.
File Usage for Client Usage for Server
name-resolve.h readonly readonly
name-resolve-common.c readonly readonly
name-resolve-stubs.c readonly -
name-resolve-skels.c - readonly
name-resolve-skelimpl.c - template for user code
Files remaining to write are listed in following table, starting with name-resolve-client.c in following chapter.
name-resolve-client.c write the client code
name-resolve-server.c write the generic code for servant creation


Example-Toolkit Helpers

Example 33. example-toolkit.c(etk_get_name_service)


 
/** resolves default name-service, usually given to application as
 * command line argument "-ORBInitRef NameService=IOR:0100000028..",
 * or since release 2.8.0 corbalocs in form of URL can be used, eg:
 * "-ORBInitRef NameService=corbaloc:iiop:HOSTNAME:PORT/NameService%00"
 */
CosNaming_NamingContext 
etk_get_name_service (CORBA_ORB         orb,
          CORBA_Environment *ev)
{
        CORBA_char   *str=NULL;
        CORBA_Object  ref
                = (CORBA_Object) CORBA_ORB_resolve_initial_references(orb,
                      "NameService",
                                                                      ev);
        if (etk_raised_exception(ev)) return CORBA_OBJECT_NIL;
  
        return (CosNaming_NamingContext) ref;
}

Example 34. example-toolkit.c(etk_name_service_bind)


/** calculate length of NULL terminated string vector */
static
guint 
id_vec_len (char *id_vec[]) 
{ 
  gint i=0; 
  for (i = 0; id_vec[i]; ++i); 
  return i;
} 

/* binds @servant object reference to unique @name at
 * @name_service. @name is a NULL terminated list of strings
 * (CORBA_char*). If error occures @ev points to exception object on
 * return.
 */
void 
etk_name_service_bind (CosNaming_NamingContext  name_service,
           CORBA_Object             servant,
           gchar                   *id_vec[], 
           CORBA_Environment       *ev)
{
  gint i = 0;
  gint len = id_vec_len (id_vec);

  /* Allocate a CosNaming::Name (sequence of CosNaming::NameComponent) */
  CosNaming_Name *name = CosNaming_Name__alloc();

  name->_buffer = CORBA_sequence_CosNaming_NameComponent_allocbuf(len);
  name->_maximum = len;
  name->_length  = 0;
  
  /* Relinquish ownership of the NameComponent to the
         * sequence. When CORBA_free is called on it later, the
         * NameComponent will be freed */ 
  CORBA_sequence_set_release (name, TRUE);

  /* iterate components of name and create sub-context
   * (directory) if needed */ 
  for (i = 0; i < len; ++i) {
    name->_length = i+1;
    name->_buffer[i].id   = CORBA_string_dup(id_vec[i]);
    name->_buffer[i].kind = CORBA_string_dup(""); 
    /* don't know what 'kind' shall be good for */ 

    if (name->_length < len) 
    {
      /* create a sub-context */ 
     CosNaming_NamingContext nc = 
        CosNaming_NamingContext_bind_new_context (name_service, 
                    name, 
                    ev);  
      if (etk_raised_exception_is_a (ev, 
                   ex_CosNaming_NamingContext_AlreadyBound))
      {
        /* ignore - ctx allread exists, this
         * is not dramatic */
        CORBA_exception_free (ev);
      }
      else if (etk_raised_exception (ev)) 
      {
        /* critical - unexpected exception  */ 
        CORBA_free (name); 
        return;
      }
    }
    else
    {
      /* Bind object to last context - use 'rebind'
       * operation in case the name has been
       * registered allready in context - note, this
       * might interfere with other service choosing
       * same name */ 
     CosNaming_NamingContext_rebind (name_service, 
              name, 
              servant,
              ev);
      if (etk_raised_exception(ev)) {
        /* critical - can not bind object */ 
        CORBA_free (name);
        return;
      }
    }
  }

  CORBA_free (name);
  return;
}

Example 35. example-toolkit.c(etk_name_service_resolve)


/* resolves object reference @return with unique @name at
 *  @name_service. @name is a NULL terminated list of strings
 *  (CORBA_char*).  If error occures @ev points to * exception object
 *  on return.
 */
CORBA_Object 
etk_name_service_resolve (CosNaming_NamingContext  name_service,
        gchar                   *id_vec[], 
        CORBA_Environment       *ev)
{
  CORBA_Object retval = CORBA_OBJECT_NIL;
  gint i = 0;
  gint len = id_vec_len (id_vec);

  /* Allocate a CosNaming::Name (sequence of CosNaming::NameComponent) */
  CosNaming_Name *name = CosNaming_Name__alloc();

  g_assert (id_vec_len (id_vec) > 0);

  name->_buffer = CORBA_sequence_CosNaming_NameComponent_allocbuf(len);
  name->_maximum = len;
  name->_length  = 0;
  
  /* Relinquish ownership of the NameComponent to the
         * sequence. When CORBA_free is called on it later, the
         * NameComponent will be freed */ 
  CORBA_sequence_set_release (name, TRUE);

  /* iterate components of name and create sub-context
   * (directory) if needed */ 
  for (i = 0; i < len; ++i) {
    name->_length = i+1;
    name->_buffer[i].id   = CORBA_string_dup(id_vec[i]);
    name->_buffer[i].kind = CORBA_string_dup(""); 
    /* don't know what 'kind' shall be good for */ 
  }
  
 retval = CosNaming_NamingContext_resolve (name_service, 
              name, 
              ev);
  
  if (etk_raised_exception (ev)) { 
    CORBA_free (name);
    return CORBA_OBJECT_NIL;
  }
  
  return retval;
}

NameResolve client

Example 36. name-resolve-client.c

/*
 * Name-Resolve client program.. Hacked by  Frank Rehberger
 * <F.Rehberger@xtradyne.de>
 *
 * Client connects to name-service and resolves object reference from server and
 * forwards console input to name-resolve-server. A dot . as single character
 * in input terminates the client.
 */

#include <stdio.h>
#include <signal.h>
#include <orbit/orbit.h>

/*
 * This header file was generated from the idl
 */

#include "name-resolve.h"
#include "examples-toolkit.h" /* provides etk_abort_if_exception */ 


static CORBA_ORB  global_orb = CORBA_OBJECT_NIL; /* global orb */
 
/* Is called in case of process signals. it invokes CORBA_ORB_shutdown()
 * function, which will terminate the processes main loop.
 */
static
void
client_shutdown (int sig)
{
        CORBA_Environment  local_ev[1];
        CORBA_exception_init(local_ev);
 
        if (global_orb != CORBA_OBJECT_NIL)
        {
                CORBA_ORB_shutdown (global_orb, FALSE, local_ev);
                etk_abort_if_exception (local_ev, "caught exception");
        }
}
 
        
/* Inits ORB @orb using @argv arguments for configuration. For each
 * ORBit options consumed from vector @argv the counter of @argc_ptr
 * will be decremented. Signal handler is set to call
 * echo_client_shutdown function in case of SIGINT and SIGTERM
 * signals.  If error occures @ev points to exception object on
 * return.
 */
static
void
client_init (int               *argc_ptr,
       char              *argv[],
             CORBA_ORB         *orb,
             CORBA_Environment *ev)
{
        /* init signal handling */
 
        signal(SIGINT,  client_shutdown);
        signal(SIGTERM, client_shutdown);
         
        /* create Object Request Broker (ORB) */
         
        (*orb) = CORBA_ORB_init(argc_ptr, argv, "orbit-local-mt-orb", ev);
        if (etk_raised_exception(ev)) return;
}

/* Releases @servant object and finally destroys @orb. If error
 * occures @ev points to exception object on return.
 */
static
void
client_cleanup (CORBA_ORB                 orb,
                CORBA_Object              service,
                CORBA_Environment        *ev)
{
        /* releasing managed object */
        CORBA_Object_release(service, ev);
        if (etk_raised_exception(ev)) return;
 
        /* tear down the ORB */
        if (orb != CORBA_OBJECT_NIL)
        {
                /* going to destroy orb.. */
                CORBA_ORB_destroy(orb, ev);
                if (etk_raised_exception(ev)) return;
        }
}

/**
 *
 */
static
void
client_run (Examples_NameResolve_Service  service,
      CORBA_Environment            *ev)
{
  char filebuffer[1024+1];

  g_print("Type any text to console to be sent to server,\n"
    "a single dot in line will terminate input\n");
  
  while( fgets(filebuffer,1024,stdin) ) {
    if( filebuffer[0] == '.' && filebuffer[1] == '\n' ) 
      break;
    
    /* chop the newline off */
    filebuffer[strlen(filebuffer)-1] = '\0';
      
    /* using the echoString method in the Echo object 
     * this is defined in the echo.h header, compiled from
     * echo.idl */

    Examples_NameResolve_Service_echoString (service,
               filebuffer,
               ev);
    if (etk_raised_exception (ev)) return;
  }
}

/*
 * main 
 */
int
main(int argc, char* argv[])
{
  Examples_NameResolve_Service service = CORBA_OBJECT_NIL;
  CosNaming_NamingContext name_service = CORBA_OBJECT_NIL;

  gchar *id[] = {"Examples", "NameResolve", "Service", NULL};

        CORBA_Environment ev[1];
        CORBA_exception_init(ev);

  client_init (&argc, argv, &global_orb, ev);
  etk_abort_if_exception(ev, "init failed");

  g_print ("Resolving service reference from name-service with id \"%s/%s/%s\"\n", id[0], id[1], id[2]);

 name_service = etk_get_name_service (global_orb, ev);
  etk_abort_if_exception(ev, "failed resolving name-service");

 service 
    = (Examples_NameResolve_Service) 
    etk_name_service_resolve (name_service, id, ev);
  etk_abort_if_exception(ev, "failed resolving service at name-service");

  client_run (service, ev);
        etk_abort_if_exception(ev, "service not reachable");
 
  client_cleanup (global_orb, service, ev);
        etk_abort_if_exception(ev, "cleanup failed");
 
        exit (0);
}

NameResolve server

Example 37. name-resolve-server.c

/*
 * echo-server program. Hacked from Echo test suite by
 * <birney@sanger.ac.uk>, ORBit2 udpate by Frank Rehberger
 * <F.Rehberger@xtradyne.de>
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <orbit/orbit.h>

#include "name-resolve-skelimpl.c"
#include "examples-toolkit.h" /* provides etk_abort_if_exception */ 

static CORBA_ORB          global_orb = CORBA_OBJECT_NIL; /* global orb */
static PortableServer_POA root_poa   = CORBA_OBJECT_NIL; /* root POA
  
/* Is called in case of process signals. it invokes CORBA_ORB_shutdown()
 * function, which will terminate the processes main loop.
 */
static
void
server_shutdown (int sig)
{
  CORBA_Environment  local_ev[1];
  CORBA_exception_init(local_ev);

        if (global_orb != CORBA_OBJECT_NIL)
        {
                CORBA_ORB_shutdown (global_orb, FALSE, local_ev);
                etk_abort_if_exception (local_ev, "caught exception");
        }
}

/* Inits ORB @orb using @argv arguments for configuration. For each
 * ORBit options consumed from vector @argv the counter of @argc_ptr
 * will be decremented. Signal handler is set to call
 * echo_server_shutdown function in case of SIGINT and SIGTERM
 * signals.  If error occures @ev points to exception object on
 * return.
 */static 
void 
server_init (int                 *argc_ptr, 
       char                *argv[],
       CORBA_ORB           *orb,
       PortableServer_POA  *poa,
       CORBA_Environment   *ev)
{
  PortableServer_POAManager  poa_manager = CORBA_OBJECT_NIL; 

  CORBA_Environment  local_ev[1];
  CORBA_exception_init(local_ev);

  /* init signal handling */
  signal(SIGINT,  server_shutdown);
  signal(SIGTERM, server_shutdown);
  
  /* create Object Request Broker (ORB) */
  
        (*orb) = CORBA_ORB_init(argc_ptr, argv, "orbit-local-mt-orb", ev);
  if (etk_raised_exception(ev)) 
    goto failed_orb;

        (*poa) = (PortableServer_POA) 
    CORBA_ORB_resolve_initial_references(*orb, "RootPOA", ev);
  if (etk_raised_exception(ev)) 
    goto failed_poa;

        poa_manager = PortableServer_POA__get_the_POAManager(*poa, ev);
  if (etk_raised_exception(ev)) 
    goto failed_poamanager;

  PortableServer_POAManager_activate(poa_manager, ev);
  if (etk_raised_exception(ev)) 
    goto failed_activation;

        CORBA_Object_release ((CORBA_Object) poa_manager, ev);
  return;

 failed_activation:
 failed_poamanager:
        CORBA_Object_release ((CORBA_Object) poa_manager, local_ev);
 failed_poa:
  CORBA_ORB_destroy(*orb, local_ev);    
 failed_orb:
  return;
}

/* Entering main loop @orb handles incoming request and delegates to
 * servants. If error occures @ev points to exception object on
 * return.
 */
static void 
server_run (CORBA_ORB          orb,
      CORBA_Environment *ev)
{
        /* enter main loop until SIGINT or SIGTERM */
  
        CORBA_ORB_run(orb, ev);
  if (etk_raised_exception(ev)) return;

        /* user pressed SIGINT or SIGTERM and in signal handler
   * CORBA_ORB_shutdown(.) has been called */
}

/* Releases @servant object and finally destroys @orb. If error
 * occures @ev points to exception object on return.
 */
static void 
server_cleanup (CORBA_ORB           orb,
    PortableServer_POA  poa,
    CORBA_Object        ref,
    CORBA_Environment  *ev)
{
  PortableServer_ObjectId   *objid       = NULL;

  objid = PortableServer_POA_reference_to_id (poa, ref, ev);
  if (etk_raised_exception(ev)) return;
    
  /* Servant: deactivatoin - will invoke  __fini destructor */
  PortableServer_POA_deactivate_object (poa, objid, ev);
  if (etk_raised_exception(ev)) return;

  PortableServer_POA_destroy (poa, TRUE, FALSE, ev);
  if (etk_raised_exception(ev)) return;

  CORBA_free (objid);

        CORBA_Object_release ((CORBA_Object) poa, ev);
  if (etk_raised_exception(ev)) return;
  
        CORBA_Object_release (ref, ev);
  if (etk_raised_exception(ev)) return;

        /* ORB: tear down the ORB */
        if (orb != CORBA_OBJECT_NIL)
        {
                /* going to destroy orb.. */
                CORBA_ORB_destroy(orb, ev);
    if (etk_raised_exception(ev)) return;
        }
}

/* Creates servant and registers in context of ORB @orb. The ORB will
 * delegate incoming requests to specific servant object.  @return
 * object reference. If error occures @ev points to exception object
 * on return.
 */
static CORBA_Object
server_activate_service (CORBA_ORB           orb,
       PortableServer_POA  poa,
       CORBA_Environment  *ev)
{
  Examples_NameResolve_Service ref = CORBA_OBJECT_NIL; 

  ref = impl_Examples_NameResolve_Service__create (poa, ev);
  if (etk_raised_exception(ev)) 
    return CORBA_OBJECT_NIL;
  
  return ref;
}

/* 
 * main 
 */

int
main (int argc, char *argv[])
{
  CORBA_Object servant                 = CORBA_OBJECT_NIL;
  CosNaming_NamingContext name_service = CORBA_OBJECT_NIL;

  gchar *id[] = {"Examples", "NameResolve", "Service", NULL};

  CORBA_Environment  ev[1];
  CORBA_exception_init(ev);
  
  server_init (&argc, argv, &global_orb, &root_poa, ev);
  etk_abort_if_exception(ev, "failed ORB init");

  servant = server_activate_service (global_orb, root_poa, ev);
  etk_abort_if_exception(ev, "failed activating service");

  g_print ("Binding service reference at name service against id: %s/%s/%s\n\n", id[0], id[1], id[2]);
  
  name_service = etk_get_name_service (global_orb, ev);
  etk_abort_if_exception(ev, "failed resolving name-service");

  etk_name_service_bind (name_service, servant, id, ev);
  etk_abort_if_exception(ev, "failed binding of service");

  server_run (global_orb, ev);
  etk_abort_if_exception(ev, "failed entering main loop");

  server_cleanup (global_orb, root_poa, servant, ev);
  etk_abort_if_exception(ev, "failed cleanup");

  exit (0);
}
  

Example 38. name-resolve-skelimpl.c

/* This is a template file generated by command */
/* orbit-idl-2 --skeleton-impl name-resolve.idl */
/* User must edit this file, inserting servant  */
/* specific code between markers. */

#include "name-resolve.h"

/*** App-specific servant structures ***/

typedef struct
{
   POA_Examples_NameResolve_Service servant;
   PortableServer_POA poa;

   /* ------ add private attributes here ------ */
   /* ------ ---------- end ------------ ------ */
} impl_POA_Examples_NameResolve_Service;

/*** Implementation stub prototypes ***/

static void
impl_Examples_NameResolve_Service__fini(impl_POA_Examples_NameResolve_Service
          * servant, CORBA_Environment * ev);
static void
impl_Examples_NameResolve_Service_echoString
(impl_POA_Examples_NameResolve_Service * servant, const CORBA_char * input,
CORBA_Environment * ev);

/*** epv structures ***/

static PortableServer_ServantBase__epv
   impl_Examples_NameResolve_Service_base_epv = {
   NULL,      /* _private data */
   (gpointer) & impl_Examples_NameResolve_Service__fini,  /* finalize routine */
   NULL,      /* default_POA routine */
};
static POA_Examples_NameResolve_Service__epv
   impl_Examples_NameResolve_Service_epv = {
   NULL,      /* _private */
   (gpointer) & impl_Examples_NameResolve_Service_echoString,

};

/*** vepv structures ***/

static POA_Examples_NameResolve_Service__vepv
   impl_Examples_NameResolve_Service_vepv = {
   &impl_Examples_NameResolve_Service_base_epv,
   &impl_Examples_NameResolve_Service_epv,
};

/*** Stub implementations ***/

static Examples_NameResolve_Service
impl_Examples_NameResolve_Service__create(PortableServer_POA poa,
            CORBA_Environment * ev)
{
   Examples_NameResolve_Service retval;
   impl_POA_Examples_NameResolve_Service *newservant;
   PortableServer_ObjectId *objid;

   newservant = g_new0(impl_POA_Examples_NameResolve_Service, 1);
   newservant->servant.vepv = &impl_Examples_NameResolve_Service_vepv;
   newservant->poa =
      (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object) poa, ev);

   POA_Examples_NameResolve_Service__init((PortableServer_Servant) newservant,
            ev);
   /* Before servant is going to be activated all
    * private attributes must be initialized.  */

   /* ------ init private attributes here ------ */
   /* ------ ---------- end ------------- ------ */

   objid = PortableServer_POA_activate_object(poa, newservant, ev);
   CORBA_free(objid);
   retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);

   return retval;
}

/**
 * impl_Examples_NameResolve_Service__fini
 * 
 * Destructor called after servant has been deactivated finally.
 * In case any active operation invocation, method call is being delayed.
 * Note, in former versions of ORBit2 this function would have been
 * named impl_Examples_NameResolve_Service__destroy.
**/
static void
impl_Examples_NameResolve_Service__fini(impl_POA_Examples_NameResolve_Service
          * servant, CORBA_Environment * ev)
{
   CORBA_Object_release((CORBA_Object) servant->poa, ev);

   /* No further remote method calls are delegated to 
    * servant and you may free your private attributes. */
   /* ------ free private attributes here ------ */
   /* ------ ---------- end ------------- ------ */

   POA_Examples_NameResolve_Service__fini((PortableServer_Servant) servant,
            ev);

   g_free(servant);
}

static void
impl_Examples_NameResolve_Service_echoString
   (impl_POA_Examples_NameResolve_Service * servant, const CORBA_char * input,
    CORBA_Environment * ev)
{
   /* ------   insert method code here   ------ */
   g_print (">> %s\n", input);
   /* ------ ---------- end ------------ ------ */
}

Compiling client & server

Example 39. Makefile

PREFIX ?= /usr
CC = gcc
TARGETS=name-resolve-client name-resolve-server
ORBIT_IDL=$(PREFIX)/bin/orbit-idl-2
CFLAGS=-DORBIT2=1 -D_REENTRANT -I$(PREFIX)/include/orbit-2.0 \
       -I$(PREFIX)/include/linc-1.0 -I$(PREFIX)/include/glib-2.0 \
       -I$(PREFIX)/lib/glib-2.0/include -g
LDFLAGS= -Wl,--export-dynamic -L$(PREFIX)/lib -lORBit-2 -llinc -lgmodule-2.0 \
             -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm       \
             -lORBitCosNaming-2 
IDLOUT=name-resolve-common.c name-resolve-stubs.c name-resolve-skels.c name-resolve.h

all: $(IDLOUT) name-resolve-client name-resolve-server

name-resolve-server.o: name-resolve-server.c name-resolve-skelimpl.c

name-resolve-client : name-resolve-client.o name-resolve-stubs.o name-resolve-common.o examples-toolkit.o
name-resolve-server : name-resolve-server.o name-resolve-skels.o name-resolve-common.o examples-toolkit.o name-resolve-skelimpl.o

$(IDLOUT): name-resolve.idl
  $(ORBIT_IDL) name-resolve.idl

%-skelimpl.c: %.idl
  $(ORBIT_IDL) --skeleton-impl $^

clean:
  rm -rf *.o *~ $(IDLOUT) *.ior *.ref

distclean: clean
  rm -rf name-resolve-client name-resolve-server