Salome HOME
Shutdown data servers scopes in driver command.
[modules/yacs.git] / src / yacsloader / driver.cxx
index 0432d5e768980f40b575ba2974b7f37186cb9e99..95f0e4de67035ac0b07e5b6df04a61f94328a5d6 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2006-2013  CEA/DEN, EDF R&D
+// Copyright (C) 2006-2021  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #include "Exception.hxx"
 #include "Executor.hxx"
 #include "parsers.hxx"
-#include "VisitorSaveState.hxx"
+#include "VisitorSalomeSaveState.hxx"
 #include "VisitorSaveSalomeSchema.hxx"
 #include "LoadState.hxx"
 #include "Dispatcher.hxx"
 #include "LinkInfo.hxx"
+#include "ObserverAsPlugin.hxx"
 
-#ifdef SALOME_KERNEL
+#include "KernelBasis.hxx"
+#include "SALOME_Launcher.hxx"
+#include "ServiceUnreachable.hxx"
+#include "SALOME_NamingService_Wrapper.hxx"
 #include "SALOME_NamingService.hxx"
 #include "SALOME_ModuleCatalog.hh"
+#include "SALOMESDS_DataServerManager.hxx"
 #include "Basics_Utils.hxx"
-#endif
 
 #include <iostream>
 #include <fstream>
 #include <signal.h>
+#include <list>
 
-#ifdef WNT
+#if defined WIN32 || defined __APPLE__
 #else
 #include <argp.h>
 #endif
@@ -57,7 +62,7 @@ const char *argp_program_bug_address ="<nepal@nepal.edf.fr>";
 static char doc[] ="driver -- a SALOME YACS graph executor";
 static char args_doc[] = "graph.xml";
 
-#ifdef WNT
+#if defined WIN32 || defined __APPLE__
 #else
 static struct argp_option options[] =
   {
@@ -72,6 +77,7 @@ static struct argp_option options[] =
     {"shutdown",        't', "level", 0,                   "Shutdown the schema: 0=no shutdown to 3=full shutdown (default 1)"},
     {"reset",           'r', "level", 0,                   "Reset the schema before execution: 0=nothing, 1=reset error nodes to ready state (default 0)"},
     {"kill-port",       'k', "port",  0,                   "Kill Salome application running on the specified port if the driver process is killed (with SIGINT or SIGTERM)"},
+    {"init_port",       'i', "value", OPTION_ARG_OPTIONAL, "Initialisation value of a port, specified as bloc.node.port=value."},
     { 0 }
   };
 #endif
@@ -90,6 +96,7 @@ struct arguments
   int shutdown;
   int reset;
   int killPort;
+  std::list<std::string> init_ports;
 };
 
 typedef struct {
@@ -98,14 +105,14 @@ typedef struct {
   string lockFile;
 } thread_st;
 
-#ifdef WNT
+#if defined WIN32 || defined __APPLE__
 static int
 #else
 static error_t
 #endif
 parse_opt (int key, char *arg, struct argp_state *state)
 {
-#ifdef WNT
+#if defined WIN32 || defined __APPLE__
 #else
   // Get the input argument from argp_parse, which we
   // know is a pointer to our arguments structure. 
@@ -159,6 +166,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case 'k':
       myArgs->killPort = atoi(arg);
       break;
+    case 'i':
+      if (arg)
+        myArgs->init_ports.push_back(std::string(arg));
+      break;
 
     case ARGP_KEY_ARG:
       if (state->arg_num >=1) // Too many arguments.
@@ -179,14 +190,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
 }
 
 // Our argp parser.
-#ifdef WNT
+#if defined WIN32 || defined __APPLE__
 #else
 static struct argp argp = { options, parse_opt, args_doc, doc };
 #endif
 
 void timer(std::string msg)
 {
-#ifdef WNT
+#if defined WIN32 || defined __APPLE__
 #else
   struct timeval tv;
   gettimeofday(&tv,NULL);
@@ -209,7 +220,7 @@ void Handler(int theSigId)
       bool isFinalDump = (strlen(myArgs.finalDump) != 0);
       if (isFinalDump)
         {
-          YACS::ENGINE::VisitorSaveState vst(p);
+          YACS::ENGINE::VisitorSalomeSaveState vst(p);
           vst.openFileDump(myArgs.finalDump);
           p->accept(&vst);
           vst.closeFileDump();
@@ -245,7 +256,7 @@ void * dumpState(void *arg)
 #endif
     string cmd = "touch " + st->lockFile;
     system(cmd.c_str());
-    YACS::ENGINE::VisitorSaveState vst(p);
+    YACS::ENGINE::VisitorSalomeSaveState vst(p);
     vst.openFileDump(st->dumpFile);
     p->accept(&vst);
     vst.closeFileDump();
@@ -271,6 +282,53 @@ sighandler_t setsig(int sig, sighandler_t handler)
 }
 #endif
 
+bool parse_init_port(const std::string& input, std::string& node, std::string& port, std::string& value)
+{
+  bool ok = true;
+  size_t pos_eq = input.find('=');
+  if(pos_eq == std::string::npos || pos_eq == input.size())
+    return false;
+  value = input.substr(pos_eq+1);
+  size_t pos_dot = input.rfind('.', pos_eq);
+  if(!pos_dot || pos_dot == std::string::npos || pos_dot >= pos_eq-1)
+    return false;
+  port = input.substr(pos_dot+1, pos_eq-pos_dot-1);
+  node = input.substr(0, pos_dot);
+  return true;
+}
+
+void InitializeSSL()
+{
+  setSSLMode(true);
+  KERNEL::getLauncherSA();
+}
+
+void shutdownServers()
+{
+  // shutdown data server scopes
+  try
+    {
+      YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
+      runTime->loadModulCatalog();
+      CORBA::ORB_ptr orb = runTime->getOrb();
+      if (orb)
+      {
+        SALOME_NamingService_Wrapper namingService(orb);
+        CORBA::Object_var objDSM(namingService.Resolve(SALOMESDS::DataServerManager::NAME_IN_NS));
+        SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(objDSM));
+        if ( !CORBA::is_nil(dsm) )
+          dsm->shutdownScopes();
+      }
+    }
+  catch(const CORBA::Exception& )
+    {
+       // ignore and continue
+    }
+  catch(ServiceUnreachable& e)
+    {
+       // ignore and continue
+    }
+}
 
 int main (int argc, char* argv[])
 {
@@ -284,12 +342,13 @@ int main (int argc, char* argv[])
   myArgs.dump = 0;
   myArgs.loadState = (char *)"";
   myArgs.xmlSchema = (char *)"";
-  myArgs.shutdown = 1;
+  myArgs.shutdown = 10;
   myArgs.reset = 0;
   myArgs.killPort = 0;
+  myArgs.init_ports.clear();
 
   // Parse our arguments; every option seen by parse_opt will be reflected in arguments.
-#ifdef WNT
+#if defined WIN32 || defined __APPLE__
 #else
   argp_parse (&argp, argc, argv, 0, 0, &myArgs);
   std::cerr << "graph = " << myArgs.args[0];
@@ -304,24 +363,34 @@ int main (int argc, char* argv[])
     std::cerr << " dumpErrorFile=" << myArgs.dumpErrorFile << std::endl;
   else
     std::cerr << std::endl;
+  std::list<std::string>::const_iterator it;
+  for(it=myArgs.init_ports.begin(); it != myArgs.init_ports.end(); it++)
+  {
+    std::cerr << (*it) << std::endl;
+  }
 #endif
 
-#ifndef WNT
+#ifndef WIN32
   setsig(SIGINT,&Handler);
   setsig(SIGTERM,&Handler);
 #endif
 
+  InitializeSSL();
+
   timer("Starting ");
-  RuntimeSALOME::setRuntime();
+  long flags = RuntimeSALOME::UsePython + RuntimeSALOME::UseCorba + RuntimeSALOME::UseXml + \
+               RuntimeSALOME::UseCpp + RuntimeSALOME::UseSalome;
+  RuntimeSALOME::setRuntime(flags, argc, argv);
 
   // Try to load the session catalog if it exists
   try
     {
       YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
+      runTime->loadModulCatalog();
       CORBA::ORB_ptr orb = runTime->getOrb();
       if (orb)
         {
-          SALOME_NamingService namingService(orb);
+          SALOME_NamingService_Wrapper namingService(orb);
           CORBA::Object_var obj = namingService.Resolve("/Kernel/ModulCatalog");
           SALOME_ModuleCatalog::ModuleCatalog_var aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
           if (! CORBA::is_nil(aModuleCatalog))
@@ -349,6 +418,31 @@ int main (int argc, char* argv[])
           std::cerr << "The imported file is probably not a YACS schema file" << std::endl;
           return 1;
         }
+      // Initialize the ports
+      for(std::list<std::string>::iterator it=myArgs.init_ports.begin(); it != myArgs.init_ports.end(); it++)
+      {
+        std::string node, port, value;
+        if(parse_init_port((*it), node, port, value))
+        {
+          std::cerr << "Initialization node=" << node
+                    << " port=" << port
+                    << " value=" << value << std::endl;
+
+          std::string init_state;
+          init_state = p->setInPortValue(node, port, value);
+          if(value.compare(init_state))
+          {
+            std::cerr << "Error on initialization:" << init_state << std::endl;
+            return 1;
+          }
+        }
+        else
+        {
+          std::cerr << "Error on parsing initialization string:" << (*it) << std::endl;
+          return 1;
+        }
+      }
+      
       //Get the parser logger
       Logger* logger=p->getLogger("parser");
       //Print errors logged if any
@@ -432,11 +526,12 @@ int main (int argc, char* argv[])
         }
 
       if (myArgs.stop)
+      {
         if (strlen(myArgs.dumpErrorFile) >0)
           executor.setStopOnError(true, myArgs.dumpErrorFile);
         else
           executor.setStopOnError(false, myArgs.dumpErrorFile);
-
+      }
       if(myArgs.display>0)
         {
           std::ofstream f("toto");
@@ -455,7 +550,7 @@ int main (int argc, char* argv[])
           st->lockFile = rootFile + ".lock";
           pthread_create(&th,NULL,&dumpState,(void*)st);
         }
-
+      YACS::ENGINE::LoadObserversPluginIfAny(p,&executor);
       cerr << "+++++++++++++++++++ start calculation +++++++++++++++++++" << endl;
       executor.RunW(p,myArgs.display, fromScratch);
       cerr << "+++++++++++++++++++  end calculation  +++++++++++++++++++" << endl;
@@ -490,7 +585,7 @@ int main (int argc, char* argv[])
       bool isFinalDump = (strlen(myArgs.finalDump) != 0);
       if (isFinalDump)
         {
-          YACS::ENGINE::VisitorSaveState vst(p);
+          YACS::ENGINE::VisitorSalomeSaveState vst(p);
           vst.openFileDump(myArgs.finalDump);
           p->accept(&vst);
           vst.closeFileDump();
@@ -498,6 +593,7 @@ int main (int argc, char* argv[])
       if(myArgs.shutdown < 999)
         {
           p->shutdown(myArgs.shutdown);
+          shutdownServers();
         }
       delete p;
       Runtime* r=YACS::ENGINE::getRuntime();
@@ -505,6 +601,7 @@ int main (int argc, char* argv[])
       r->fini();
       delete r;
       delete disp;
+      YACS::ENGINE::UnLoadObserversPluginIfAny();
       return return_value;
     }
   catch (YACS::Exception& e)