From 0d6017d21648c2ddc4264c72c691deb0828e4f06 Mon Sep 17 00:00:00 2001
From: Joseph Mirabel <jmirabel@laas.fr>
Date: Mon, 4 Feb 2019 09:37:58 +0100
Subject: [PATCH] Provide API and option to bypass omni name service.

---
 include/gepetto/gui/settings.hh        |   1 +
 include/gepetto/viewer/corba/server.hh |   4 +-
 src/gepetto/corbaserver/client.py      |  92 ++++++++++++---------
 src/gui/mainwindow.cc                  |   2 +-
 src/gui/settings.cc                    |  10 +++
 src/server-private.cc                  |  15 +++-
 src/server-private.hh                  |  11 ++-
 src/server.cc                          | 108 ++++++++++++++-----------
 8 files changed, 151 insertions(+), 92 deletions(-)

diff --git a/include/gepetto/gui/settings.hh b/include/gepetto/gui/settings.hh
index 713d653..d482b61 100644
--- a/include/gepetto/gui/settings.hh
+++ b/include/gepetto/gui/settings.hh
@@ -44,6 +44,7 @@ namespace gepetto {
       bool noPlugin;
       bool autoWriteSettings;
       bool startGepettoCorbaServer;
+      bool useNameService;
 
       int refreshRate;
 
diff --git a/include/gepetto/viewer/corba/server.hh b/include/gepetto/viewer/corba/server.hh
index c82ca7d..7cec3dd 100644
--- a/include/gepetto/viewer/corba/server.hh
+++ b/include/gepetto/viewer/corba/server.hh
@@ -64,7 +64,7 @@ namespace graphics
       ///       CORBA request processing if this library is run from an openGL
       ///       based GUI, since OpenGL does not support multithreading.
       Server (WindowsManagerPtr_t windowsManager, int argc,
-          const char* argv[], bool multiThread = false);
+          const char* argv[], bool multiThread = false, bool useNameService = false);
 
       /// \brief Shutdown CORBA server
       ~Server ();
@@ -93,7 +93,7 @@ namespace graphics
       /// \param argc, argv parameter to feed ORB initialization.
       /// \param multiThread whether the server may process request using
       ///        multithred policy.
-      void initORBandServers (int argc, const char* argv[], bool multiThread);
+      void initORBandServers (int argc, const char* argv[], bool multiThread, bool useNameService);
 
       /// \}
 
diff --git a/src/gepetto/corbaserver/client.py b/src/gepetto/corbaserver/client.py
index a04b7cf..38e7145 100644
--- a/src/gepetto/corbaserver/client.py
+++ b/src/gepetto/corbaserver/client.py
@@ -23,35 +23,42 @@ class Client:
 
   defaultClients = [('gui', 'GraphicalInterface')]
 
-  def makeClient(self, serviceName):
-    """
-    Create a client to a new CORBA service and add it to this class.
-    """
+  def initWithNameService (self, urlNameService):
+    obj = self.orb.string_to_object (urlNameService)
+    self.rootContext = obj._narrow(CosNaming.NamingContext)
+    if self.rootContext is None:
+      raise CorbaError ('Failed to narrow the root context')
+
     name = [CosNaming.NameComponent ("gepetto", "viewer"),
-            CosNaming.NameComponent ("corbaserver", serviceName [0])]
+            CosNaming.NameComponent ("corbaserver", "gui")]
 
     try:
       obj = self.rootContext.resolve (name)
     except CosNaming.NamingContext.NotFound:
-      raise CorbaError (
-        'failed to find the service ``{0}\'\''.format (serviceName [0]))
+      raise CorbaError ('Failed to find the service "gui"')
 
     try:
-      client = obj._narrow (gepetto.corbaserver.__dict__
-                            [serviceName [1]])
+      client = obj._narrow (gepetto.corbaserver.GraphicalInterface)
     except KeyError:
-      raise CorbaError ('invalid service name ``{0}\'\''.format \
-                          (serviceName [0]))
+      raise CorbaError ('Invalid service name "gui"')
+
+    if client is None:
+      # This happens when stubs from client and server are not synchronized.
+      raise CorbaError ( 'Failed to narrow client for service named "gui"')
+
+    self.gui = client
+
+  def initWithDirectLink (self, url):
+    obj = self.orb.string_to_object (url)
+    client = obj._narrow(gepetto.corbaserver.GraphicalInterface)
 
     if client is None:
       # This happens when stubs from client and server are not synchronized.
-      raise CorbaError (
-        'failed to narrow client for service named ``{0}\'\''.format
-        (serviceName [0]))
-    self.__dict__[serviceName [0]] = client
+      raise CorbaError ( 'Failed to narrow client for service named "gui"')
 
+    self.gui = client
 
-  def __init__(self, clients = defaultClients, url = None, host = None):
+  def __init__(self, clients = defaultClients, url = None, host = None, port = None):
     """
     Initialize CORBA and create default clients.
     :param url: URL in the IOR, corbaloc, corbalocs, and corbanames formats.
@@ -60,19 +67,28 @@ class Client:
                 If None, url is initialized with param host, or alternatively with _getIIOPurl
     :param host: if not None, url is set to = "corbaloc:iiop:" + str(host) + "/NameService"
     """
-    if host is not None:
-        url = "corbaloc:iiop:" + str(host) + "/NameService"
-    elif url is None:
-        url = _getIIOPurl()
     import sys
     self.orb = CORBA.ORB_init (sys.argv, CORBA.ORB_ID)
-    obj = self.orb.string_to_object (url)
-    self.rootContext = obj._narrow(CosNaming.NamingContext)
-    if self.rootContext is None:
-      raise CorbaError ('failed to narrow the root context')
 
-    for client in clients:
-      self.makeClient (client)
+    if url is not None:
+        try:
+            self.initWithDirectLink (url)
+        except CorbaError:
+            pass
+        if self.gui is None:
+            self.initWithNameService (url)
+    else:
+        urlNameService = _getIIOPurl(service="NameService", host=host,
+                port = port if port else 2809)
+        urlGepettoGui = _getIIOPurl(service="gepetto-gui", host=host,
+                port = port if port else 12321)
+        try:
+            self.initWithDirectLink (urlGepettoGui)
+        except CorbaError as e:
+            print e
+            pass
+        if self.gui is None:
+            self.initWithNameService (urlNameService)
 
     # In the python interpreter of gepetto-gui, gui.createWindow
     # crashes for an obscure reason. This hack makes it work.
@@ -84,7 +100,7 @@ class Client:
       # At this point, we are NOT in the python interpreter of gepetto-gui
       pass
 
-def _getIIOPurl ():
+def _getIIOPurl (service="NameService", host=None, port=None):
   """
   Returns "corbaloc:iiop:<host>:<port>/NameService"
   where host and port are, in this order of priority:
@@ -92,21 +108,23 @@ def _getIIOPurl ():
   - /gepetto_viewer/host, /gepetto_viewer/port ROS parameters
   - use default values ("localhost", 2809)
   """
-  host = "localhost"
-  port = 2809
+  _host = "localhost"
+  _port = 2809
   import os
   try:
     import rospy
     # Check is ROS master is reachable.
     if rospy.client.get_master().target is not None:
-      host = rospy.get_param("/gepetto_viewer/host", host)
-      port = rospy.get_param("/gepetto_viewer/port", port)
+      _host = rospy.get_param("/gepetto_viewer/host", _host)
+      _port = rospy.get_param("/gepetto_viewer/port", _port)
   except:
     pass
-  host = os.getenv ("GEPETTO_VIEWER_HOST", host)
-  port = os.getenv ("GEPETTO_VIEWER_PORT", port)
-  if host is None and port is None:
-      url = "corbaloc:iiop:/NameService"
+  _host = os.getenv ("GEPETTO_VIEWER_HOST", _host)
+  _port = os.getenv ("GEPETTO_VIEWER_PORT", _port)
+  if host: _host = host
+  if port: _port = port
+  if _host is None and _port is None:
+      url = "corbaloc:iiop:"
   else:
-      url = "corbaloc:iiop:{}:{}/NameService".format(host, port)
-  return url
+      url = "corbaloc:iiop:{}:{}".format(_host, _port)
+  return url + "/" + service
diff --git a/src/gui/mainwindow.cc b/src/gui/mainwindow.cc
index 272bfc2..618a698 100644
--- a/src/gui/mainwindow.cc
+++ b/src/gui/mainwindow.cc
@@ -71,7 +71,7 @@ namespace gepetto {
         const char** argv = settings_->makeOmniORBargs (argc);
         osgServer_ = new CorbaServer (new ViewerServerProcess (
               new graphics::corbaServer::Server (osgViewerManagers_,
-                  argc, argv, true)));
+                  argc, argv, true, settings_->useNameService)));
         osgServer_->start();
       }
       // This scene contains elements required for User Interaction.
diff --git a/src/gui/settings.cc b/src/gui/settings.cc
index 446d182..a9acae8 100644
--- a/src/gui/settings.cc
+++ b/src/gui/settings.cc
@@ -41,6 +41,7 @@ namespace gepetto {
       , verbose (false)
       , noPlugin (false)
       , startGepettoCorbaServer (true)
+      , useNameService (false)
       , refreshRate (30)
       , captureDirectory ()
       , captureFilename ("screenshot")
@@ -104,6 +105,7 @@ namespace gepetto {
       au->addCommandLineOption("-P or --no-plugin", "do not load any plugin");
       au->addCommandLineOption("-w or --auto-write-settings", "write the settings in the configuration file");
       au->addCommandLineOption("--no-viewer-server", "do not start the Gepetto Viewer server");
+      au->addCommandLineOption("--use-nameservice" , "The server will be registered to the Omni NameService");
 
       // 2. Read configuration files
       if (arguments.read("-c", configurationFile) || arguments.read("--config-file", configurationFile)) {}
@@ -126,6 +128,7 @@ namespace gepetto {
       noPlugin =                (arguments.read("-P") || arguments.read("--no-plugin"));
       autoWriteSettings =       (arguments.read("-w") || arguments.read("--auto-write-settings"));
       startGepettoCorbaServer = (!arguments.read("--no-viewer-server"));
+      while (arguments.read ("--use-nameservice", useNameService)) {}
 
       std::string opt;
       while (arguments.read ("--add-robot", opt))
@@ -155,6 +158,9 @@ namespace gepetto {
           ++i;
       }
 
+      if (!omniORBargv_.contains("-ORBendPoint"))
+        addOmniORB ("-ORBendPoint", "::localhost:12321");
+
       if (genAndQuit && retVal < 1) retVal = 1;
 
       if (help != osg::ApplicationUsage::NO_HELP) {
@@ -275,6 +281,7 @@ namespace gepetto {
         << nl << tab << "Verbose:                " << tab << verbose
         << nl << tab << "No plugin:              " << tab << noPlugin
         << nl << tab << "Start Viewer server:    " << tab << startGepettoCorbaServer
+        << nl << tab << "Use omni name service:  " << tab << useNameService
         << nl << tab << "Refresh rate:           " << tab << refreshRate
 
         << nl << nl << "Screen capture options:"
@@ -373,6 +380,8 @@ namespace gepetto {
         int nbMultiSamples = 4;
         GET_PARAM(nbMultiSamples, int, toInt);
         ds->setNumMultiSamples(nbMultiSamples);
+
+        GET_PARAM(useNameService, bool, toBool);
         env.endGroup ();
 
         env.beginGroup("plugins");
@@ -453,6 +462,7 @@ namespace gepetto {
       env.beginGroup("viewer");
       env.setValue ("refreshRate", refreshRate);
       env.setValue ("nbMultiSamples", ds->getNumMultiSamples());
+      env.setValue ("useNameService", useNameService);
       env.endGroup ();
 
       env.beginGroup("plugins");
diff --git a/src/server-private.cc b/src/server-private.cc
index 79641db..017cd7c 100644
--- a/src/server-private.cc
+++ b/src/server-private.cc
@@ -38,10 +38,9 @@ namespace graphics
       }
 
       void
-      Server::createAndActivateServers (corbaServer::Server* inServer)
+      Server::createServant (corbaServer::Server* inServer)
       {
 	graphicalInterfaceServant_ = new GraphicalInterface (inServer);
-	graphicalInterfaceServantid_ = poa_->activate_object(graphicalInterfaceServant_);
       }
 
       void Server::deactivateAndDestroyServers()
@@ -49,7 +48,6 @@ namespace graphics
 	  poa_->deactivate_object(*graphicalInterfaceServantid_);
       }
 
-
       void Server::createContext ()
       {
 	CosNaming::NamingContext_var rootContext;
@@ -97,6 +95,17 @@ namespace graphics
 	}
       }
 
+      void Server::initRootPOA ()
+      {
+	graphicalInterfaceServantid_ = poa_->activate_object(graphicalInterfaceServant_);
+      }
+
+      void Server::initOmniINSPOA ()
+      {
+        objectId_ = PortableServer::string_to_ObjectId("gepetto-gui");
+        poa_->activate_object_with_id(objectId_, graphicalInterfaceServant_);
+      }
+
       void Server::bindObjectToName(Object_ptr objref,
 				    CosNaming::Name objectName)
       {
diff --git a/src/server-private.hh b/src/server-private.hh
index f0b549d..501a32a 100644
--- a/src/server-private.hh
+++ b/src/server-private.hh
@@ -25,13 +25,18 @@ namespace graphics
       public:
 	~Server ();
 
-	/// \brief Create and activate the Corba servers.
-	void createAndActivateServers (graphics::corbaServer::Server* server);
+        void initRootPOA ();
+
+        void initOmniINSPOA ();
+
+	void createServant (graphics::corbaServer::Server* server);
 
       private:
 	CORBA::ORB_var orb_;
 	PortableServer::POA_var poa_;
-	GraphicalInterface* graphicalInterfaceServant_;
+        PortableServer::ObjectId_var objectId_;
+        bool useNameService_;
+        GraphicalInterface* graphicalInterfaceServant_;
 
 	/// \brief It seems that we need to store this object to
 	/// deactivate the server.
diff --git a/src/server.cc b/src/server.cc
index aa436ed..a025f3b 100644
--- a/src/server.cc
+++ b/src/server.cc
@@ -42,11 +42,11 @@ namespace graphics
 
 
     Server::Server(WindowsManagerPtr_t wm, int argc, const char *argv[],
-        bool inMultiThread) : windowsManager_ (wm)
+        bool inMultiThread, bool useNameService) : windowsManager_ (wm)
     {
       private_ = new impl::Server;
 
-      initORBandServers (argc, argv, inMultiThread);
+      initORBandServers (argc, argv, inMultiThread, useNameService);
     }
 
     /// \brief Shutdown CORBA server
@@ -60,7 +60,7 @@ namespace graphics
     /// CORBA SERVER INITIALIZATION
 
     void Server::initORBandServers(int argc, const char* argv[],
-				   bool inMultiThread)
+				   bool inMultiThread, bool useNameService)
     {
       Object_var obj;
       PortableServer::ThreadPolicy_var threadPolicy;
@@ -73,54 +73,70 @@ namespace graphics
 	throw std::runtime_error (msg.c_str ());
       }
       /// ORB init
-      obj = private_->orb_->resolve_initial_references("RootPOA");
-
-      /// Create thread policy
-      //
-      // Make the CORBA object single-threaded to avoid GUI krash
-      //
-      // Create a sigle threaded policy object
-      rootPoa = PortableServer::POA::_narrow(obj);
-
-      if (inMultiThread) {
-	threadPolicy = rootPoa->create_thread_policy
-	  (PortableServer::ORB_CTRL_MODEL);
+      if (useNameService) {
+        obj = private_->orb_->resolve_initial_references("RootPOA");
+
+        /// Create thread policy
+        //
+        // Make the CORBA object single-threaded to avoid GUI krash
+        //
+        // Create a sigle threaded policy object
+        rootPoa = PortableServer::POA::_narrow(obj);
+
+        if (inMultiThread) {
+          threadPolicy = rootPoa->create_thread_policy
+            (PortableServer::ORB_CTRL_MODEL);
+        }
+        else {
+          threadPolicy = rootPoa->create_thread_policy
+            (PortableServer::MAIN_THREAD_MODEL);
+        }
+        /// Duplicate thread policy
+        PolicyList policyList;
+        policyList.length(1);
+        policyList[0] = PortableServer::ThreadPolicy::_duplicate(threadPolicy);
+
+        try {
+          private_->poa_ = rootPoa->create_POA
+            ("child", PortableServer::POAManager::_nil(), policyList);
+        } catch (PortableServer::POA::AdapterAlreadyExists& /*e*/) {
+          private_->poa_ = rootPoa->find_POA ("child", false);
+        }
+        // Destroy policy object
+        threadPolicy->destroy();
+      } else {
+        // TODO: There is no way to use omniINSPOA with a different policy.
+        // A rather easy workaround can be found here:
+        // http://www.omniorb-support.com/pipermail/omniorb-list/2006-January/027358.html
+        obj = private_->orb_->resolve_initial_references("omniINSPOA");
+        private_->poa_ = PortableServer::POA::_narrow(obj);
       }
-      else {
-	threadPolicy = rootPoa->create_thread_policy
-	  (PortableServer::MAIN_THREAD_MODEL);
-      }
-      /// Duplicate thread policy
-      PolicyList policyList;
-      policyList.length(1);
-      policyList[0] = PortableServer::ThreadPolicy::_duplicate(threadPolicy);
-
-      try {
-        private_->poa_ = rootPoa->create_POA
-          ("child", PortableServer::POAManager::_nil(), policyList);
-      } catch (PortableServer::POA::AdapterAlreadyExists& /*e*/) {
-        private_->poa_ = rootPoa->find_POA ("child", false);
-      }
-      // Destroy policy object
-      threadPolicy->destroy();
-      private_->createAndActivateServers(this);
+
+      private_->useNameService_ = useNameService;
+      private_->createServant(this);
+      if (useNameService)
+        private_->initRootPOA();
+      else
+        private_->initOmniINSPOA();
     }
 
     void Server::startCorbaServer()
     {
-      // Obtain a reference to objects, and register them in
-      // the naming service.
-      Object_var graphicalInterfaceObj = private_->graphicalInterfaceServant_->_this();
-
-      private_->createContext ();
-      // Bind graphicalInterfaceObj with name graphicalinterface to the Context:
-      CosNaming::Name objectName;
-      objectName.length(1);
-      objectName[0].id   = (const char*) "corbaserver";   // string copied
-      objectName[0].kind = (const char*) "gui"; // string copied
-
-      private_->bindObjectToName(graphicalInterfaceObj, objectName);
-      private_->graphicalInterfaceServant_->_remove_ref();
+      if (private_->useNameService_) {
+        // Obtain a reference to objects, and register them in
+        // the naming service.
+        Object_var graphicalInterfaceObj = private_->graphicalInterfaceServant_->_this();
+
+        private_->createContext ();
+        // Bind graphicalInterfaceObj with name graphicalinterface to the Context:
+        CosNaming::Name objectName;
+        objectName.length(1);
+        objectName[0].id   = (const char*) "corbaserver";   // string copied
+        objectName[0].kind = (const char*) "gui"; // string copied
+
+        private_->bindObjectToName(graphicalInterfaceObj, objectName);
+        private_->graphicalInterfaceServant_->_remove_ref();
+      }
 
       PortableServer::POAManager_var pman = private_->poa_->the_POAManager();
       pman->activate();
-- 
GitLab