From 46111a9d16cf67eb43947ad768708dddab83d4d1 Mon Sep 17 00:00:00 2001 From: abn Date: Mon, 29 Jun 2015 13:36:55 +0200 Subject: [PATCH] Moved PVSERVER CORBA engine from PARAVIS to GUI. PVSERVER is now a simple CORBA service, not inheriting from EngineComponent class. GUI can now be compiled with the PVViewer and without the PARAVIS module. --- CMakeLists.txt | 2 +- SalomeGUIConfig.cmake.in | 1 + idl/CMakeLists.txt | 11 ++ idl/PVSERVER_Gen.idl | 72 +++++++++ src/CMakeLists.txt | 1 + src/LightApp/LightApp_Application.cxx | 5 +- src/PVServerService/CMakeLists.txt | 62 ++++++++ src/PVServerService/ENGINE/CMakeLists.txt | 35 +++++ src/PVServerService/ENGINE/PVSERVER.py | 63 ++++++++ src/PVServerService/ENGINE/PVSERVER_impl.py | 138 ++++++++++++++++++ src/PVServerService/ENGINE/PVSERVER_utils.py | 93 ++++++++++++ src/PVServerService/PVServerService.h | 33 +++++ .../PVServer_ServiceWrapper.cxx} | 58 ++++---- .../PVServer_ServiceWrapper.h} | 20 +-- .../ServiceLoader/CMakeLists.txt | 69 +++++++++ .../ServiceLoader/PVServer_ServiceLoader.cxx | 104 +++++++++++++ .../ServiceLoader/PVServer_ServiceLoader.h | 50 +++++++ .../ServiceLoader/PVServer_ServiceLoader.i | 14 ++ src/PVViewer/CMakeLists.txt | 4 +- src/PVViewer/PVViewer_Core.cxx | 1 - src/PVViewer/PVViewer_Core.h | 2 +- src/PVViewer/PVViewer_ViewManager.cxx | 12 +- src/PVViewer/PVViewer_ViewManager.h | 4 +- 23 files changed, 801 insertions(+), 53 deletions(-) create mode 100644 idl/PVSERVER_Gen.idl create mode 100644 src/PVServerService/CMakeLists.txt create mode 100644 src/PVServerService/ENGINE/CMakeLists.txt create mode 100644 src/PVServerService/ENGINE/PVSERVER.py create mode 100644 src/PVServerService/ENGINE/PVSERVER_impl.py create mode 100644 src/PVServerService/ENGINE/PVSERVER_utils.py create mode 100644 src/PVServerService/PVServerService.h rename src/{PVViewer/PVViewer_EngineWrapper.cxx => PVServerService/PVServer_ServiceWrapper.cxx} (56%) rename src/{PVViewer/PVViewer_EngineWrapper.h => PVServerService/PVServer_ServiceWrapper.h} (77%) create mode 100644 src/PVServerService/ServiceLoader/CMakeLists.txt create mode 100644 src/PVServerService/ServiceLoader/PVServer_ServiceLoader.cxx create mode 100644 src/PVServerService/ServiceLoader/PVServer_ServiceLoader.h create mode 100644 src/PVServerService/ServiceLoader/PVServer_ServiceLoader.i diff --git a/CMakeLists.txt b/CMakeLists.txt index 2929ce0dc..965682114 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -350,7 +350,7 @@ ENDIF(SALOME_USE_PYVIEWER) # ParaView viewer specific targets: IF(SALOME_USE_PVVIEWER) - LIST(APPEND _${PROJECT_NAME}_exposed_targets PVViewer) + LIST(APPEND _${PROJECT_NAME}_exposed_targets PVViewer PVServerService) ENDIF() diff --git a/SalomeGUIConfig.cmake.in b/SalomeGUIConfig.cmake.in index c7ea0b97a..5010a661f 100644 --- a/SalomeGUIConfig.cmake.in +++ b/SalomeGUIConfig.cmake.in @@ -218,6 +218,7 @@ SET(GUI_ViewerTools ViewerTools) SET(GUI_ViewerData ViewerData) SET(GUI_VTKViewer VTKViewer) SET(GUI_PVViewer PVViewer) +SET(GUI_PVServerService PVServerService) SET(GUI_vtkEDFOverloads vtkEDFOverloads) SET(GUI_vtkTools vtkTools) SET(GUI_SalomeGuiHelpers SalomeGuiHelpers) diff --git a/idl/CMakeLists.txt b/idl/CMakeLists.txt index 8bfbf3262..31b4dc736 100755 --- a/idl/CMakeLists.txt +++ b/idl/CMakeLists.txt @@ -38,3 +38,14 @@ SET(_idl_link_flags OMNIORB_ADD_MODULE(SalomeIDLGUI "${SalomeIDLGUI_IDLSOURCES}" "${_idl_include_dirs}" "${_idl_link_flags}") INSTALL(TARGETS SalomeIDLGUI EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) + +######################################################################## +### PVServer service: +SET(SalomeIDLPVSERVER_IDLSOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/PVSERVER_Gen.idl + ) +# Demand Python generation: +SET(OMNIORB_PYTHON_BACKEND 1) +OMNIORB_ADD_MODULE(SalomeIDLPVServer "${SalomeIDLPVSERVER_IDLSOURCES}" "${_idl_include_dirs}" "${_idl_link_flags}") +INSTALL(TARGETS SalomeIDLPVServer EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) + diff --git a/idl/PVSERVER_Gen.idl b/idl/PVSERVER_Gen.idl new file mode 100644 index 000000000..226f94000 --- /dev/null +++ b/idl/PVSERVER_Gen.idl @@ -0,0 +1,72 @@ +// Copyright (C) 2010-2015 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Adrien Bruneton (CEA) + + +#ifndef __PVSERVER_GEN__ +#define __PVSERVER_GEN__ + +#include "SALOME_Exception.idl" + +/*! + PVSERVER interface. This is a standalone service, not inheriting the EngineComponent interfaces. + + The main service provided by the interface is to give to the caller the URL of the pvserver, and to launch it + if it is not already started. + The connection to the ParaView's pvserver should then be done using ParaView's API directly. +*/ +module PVSERVER_ORB { + + /*! + * \brief The main interface class for PVSERVER CORBA service. + * Instantiation of this class has to be done before access to any other PARAVIS interfaces + */ + interface PVSERVER_Gen + { + + /*! + * \brief Returns IOR of the current object. + */ + string GetIOR(); + + /*! If a pvserver is already started, returns its current URL, regardless of the provided + * parameters. + * If not, start a pvserver on the machine hosting the PARAVIS engine and on the given port. + * If port <= 0, a free port is automatically detected, starting from the usual 11111 pvserver port. + */ + string FindOrStartPVServer(in long port); + + /*! Tries to stop the PVserver currently running (send KILL). + * @return false if no server was running, true otherwise. + */ + boolean StopPVServer(); + + /*! Indicates if the GUI process is already connected to the pvserver. + * This avoids multiple attempts to connect from a single thread (makes ParaView crash). */ + void SetGUIConnected(in boolean isConnected); + + /*! Indicates if the GUI process is already connected to the pvserver. + * This avoids multiple attempts to connect from a single thread (makes ParaView crash). */ + boolean GetGUIConnected(); + + }; + +}; + +#endif \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a205bd00e..6435a1ccf 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,6 +107,7 @@ ENDIF(SALOME_USE_GRAPHICSVIEW) # ParaView Viewer IF(SALOME_USE_PVVIEWER) ADD_SUBDIRECTORY(PVViewer) + ADD_SUBDIRECTORY(PVServerService) ENDIF() ## diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index ab27384ed..4617cad86 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -755,10 +755,7 @@ void LightApp_Application::createActions() createActionForViewer( NewGraphicsViewId, newWinMenu, QString::number( 5 ), Qt::ALT+Qt::Key_C ); #endif #ifndef DISABLE_PVVIEWER - QStringList aModuleNames; - modules( aModuleNames, false ); - if ( aModuleNames.contains( "ParaViS", Qt::CaseInsensitive ) ) - createActionForViewer( NewPVViewId, newWinMenu, QString::number( 6 ), Qt::ALT+Qt::Key_A ); + createActionForViewer( NewPVViewId, newWinMenu, QString::number( 6 ), Qt::ALT+Qt::Key_A ); #endif #ifndef DISABLE_PYVIEWER createActionForViewer( NewPyViewerId, newWinMenu, QString::number( 7 ), Qt::ALT+Qt::Key_Y ); diff --git a/src/PVServerService/CMakeLists.txt b/src/PVServerService/CMakeLists.txt new file mode 100644 index 000000000..eeda9c4be --- /dev/null +++ b/src/PVServerService/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (C) 2010-2015 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +ADD_SUBDIRECTORY(ENGINE) +IF(NOT SALOME_LIGHT_ONLY) + ADD_SUBDIRECTORY(ServiceLoader) +ENDIF() + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR} + ${KERNEL_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/src/PyInterp + ) + +ADD_DEFINITIONS( + ${KERNEL_DEFINITIONS} + ${PYTHON_DEFINITIONS} + ) + +SET(_link_LIBRARIES + ${KERNEL_OpUtil} # class SALOME_Exception + PyInterp # class PyLockWrapper + ) + +# --- headers --- +SET(PVServer_HEADERS + PVServerService.h + PVServer_ServiceWrapper.h +) + +# --- sources --- +SET(PVServer_SOURCES + PVServer_ServiceWrapper.cxx + ) + +SET(PVServer_SWIG + PVServer_ServiceLoader.i + ) + +# --- rules --- +ADD_LIBRARY(PVServerService ${PVServer_SOURCES}) +TARGET_LINK_LIBRARIES(PVServerService ${_link_LIBRARIES}) +INSTALL(TARGETS PVServerService EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) + +# --- header installation --- +INSTALL(FILES ${PVServer_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/PVServerService/ENGINE/CMakeLists.txt b/src/PVServerService/ENGINE/CMakeLists.txt new file mode 100644 index 000000000..35dfade52 --- /dev/null +++ b/src/PVServerService/ENGINE/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (C) 2010-2015 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +SET(_bin_SCRIPTS + PVSERVER_impl.py + ) + +IF(NOT SALOME_LIGHT_ONLY) + LIST(APPEND _bin_SCRIPTS + PVSERVER.py + PVSERVER_utils.py + ) +ENDIF() + + +# --- rules --- +SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_SCRIPT_PYTHON}) + + \ No newline at end of file diff --git a/src/PVServerService/ENGINE/PVSERVER.py b/src/PVServerService/ENGINE/PVSERVER.py new file mode 100644 index 000000000..c3396b6e6 --- /dev/null +++ b/src/PVServerService/ENGINE/PVSERVER.py @@ -0,0 +1,63 @@ +# Copyright (C) 2007-2015 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Adrien BRUNETON (CEA) +# + +import PVSERVER_ORB__POA +from SALOME_NamingServicePy import SALOME_NamingServicePy_i +from PVSERVER_impl import PVSERVER_impl, MESSAGE + +class PVSERVER(PVSERVER_ORB__POA.PVSERVER_Gen, + PVSERVER_impl): + """ + Construct an instance of PVSERVER *service*. + The class PVSERVER implements the CORBA interface PVSERVER_Gen (see PVSERVER_Gen.idl). + It is NOT inherited from the classes SALOME_ComponentPy_i, as we present + the class as a pure CORBA service, not as a standard SALOME component. + """ + def __init__ ( self, orb, poa, contID, containerName, instanceName, + interfaceName ): + + + PVSERVER_impl.__init__(self) + + self._orb = orb + self._poa = poa + self._instanceName = instanceName +# self._interfaceName = interfaceName + self._containerName = containerName +# self._contId = contID + + self._naming_service = SALOME_NamingServicePy_i(self._orb) + Component_path = self._containerName + "/" + self._instanceName + MESSAGE( 'SALOME_ComponentPy_i Register' + str( Component_path ) ) + id_o = poa.activate_object(self) + compo_o = poa.id_to_reference(id_o) + + ## And launch registration + ## + self._naming_service.Register(compo_o, Component_path) + + """ Override base class destroy to make sure we try to kill the pvserver + before leaving. + """ + def destroy(self): + # TODO + self.StopPVServer() + \ No newline at end of file diff --git a/src/PVServerService/ENGINE/PVSERVER_impl.py b/src/PVServerService/ENGINE/PVSERVER_impl.py new file mode 100644 index 000000000..cdec0ee06 --- /dev/null +++ b/src/PVServerService/ENGINE/PVSERVER_impl.py @@ -0,0 +1,138 @@ +# Copyright (C) 2007-2015 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Adrien Bruneton (CEA) +# + +import subprocess as subp +import socket +from time import sleep +import os +from SALOME import SALOME_Exception +#from SALOME_utilities import MESSAGE + +def MESSAGE(m): + """ Debug function """ + pass + #os.system("echo \"%s\" >> /tmp/paravis_log.txt" % m) + +class PVSERVER_impl(object): + """ The core implementation (non CORBA, or Study related). + See the IDL for the documentation. + """ + MAX_PVSERVER_PORT_TRIES = 1000 # Maximum number of tries to get a free port for the PVServer + PVSERVER_DEFAULT_PORT = 11111 # First port being tried to launch the pvserver + + def __init__(self): + self.pvserverPort = -1 + self.pvserverPop = None # Popen object from subprocess module + self.isGUIConnected = False # whether there is an active connection from the GUI. + try: + import paraview + tmp=paraview.__file__ + except: + raise Exception("PVSERVER_Impl.__init__ : \"import paraview\" failed !") + # deduce dynamically PARAVIEW_ROOT_DIR from the paraview module location + self.PARAVIEW_ROOT_DIR = None + ZE_KEY_TO_FIND_PV_ROOT_DIR="lib" + li=tmp.split(os.path.sep) ; li.reverse() + if ZE_KEY_TO_FIND_PV_ROOT_DIR not in li: + raise SALOME_Exception(SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, + "PVSERVER_Impl.__init__ : error during dynamic deduction of PARAVIEW_ROOT_DIR : Loc of paraview module is \"%s\" ! \"%s\" is supposed to be the key to deduce it !"%(tmp,ZE_KEY_TO_FIND_PV_ROOT_DIR), + "PVSERVER.py", 0)) + li=li[li.index("lib")+1:] ; li.reverse() + self.PARAVIEW_ROOT_DIR = os.path.sep.join(li) + + """ + Private. Identify a free port to launch the PVServer. + This is done by trying to bind a socket on the port. + We are still subject to a race condition between this detection mechanism and the actual launch of the pvserver + itself ... + """ + def __getFreePort(self, startPort): + cnt = 0 + currPort = startPort + while cnt < self.MAX_PVSERVER_PORT_TRIES: + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(('', currPort)) + s.close() + return currPort + except socket.error as e: + cnt += 1 + currPort += 1 + pass + raise SALOME_Exception(SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, + "[PVSERVER] maximum number of tries to retrieve a free port for the PVServer", + "PVSERVER.py", 0)) + + def FindOrStartPVServer( self, port ): + MESSAGE("[PVSERVER] FindOrStartPVServer ...") + host = "localhost" + alive = True + if self.pvserverPop is None: + alive = False + else: + # Poll active server to check if still alive + self.pvserverPop.poll() + if not self.pvserverPop.returncode is None: # server terminated + alive = False + + if alive: + return "cs://%s:%d" % (host, self.pvserverPort) + + # (else) Server not alive, start it: + pvServerPath = os.path.join(self.PARAVIEW_ROOT_DIR, 'bin', 'pvserver') + opt = [] + if port <= 0: + port = self.__getFreePort(self.PVSERVER_DEFAULT_PORT) + self.pvserverPop = subp.Popen([pvServerPath, "--multi-clients", "--server-port=%d" % port, "--use-offscreen-rendering"]) + sleep(3) # Give some time to the server to start up to avoid + # ugly messages on the client side saying that it cannot connect + # Is PID still alive? If yes, consider that the launch was successful + self.pvserverPop.poll() + if self.pvserverPop.returncode is None: + success = True + self.pvserverPort = port + MESSAGE("[PVSERVER] pvserver successfully launched on port %d" % port) + else: + raise SALOME_Exception(SALOME.ExceptionStruct(SALOME.INTERNAL_ERROR, + "[PVSERVER] Unable to start PVServer on port %d!" % port, + "PVSERVER.py", 0)) + return "cs://%s:%d" % (host, self.pvserverPort) + + def StopPVServer( self ): + MESSAGE("[PVSERVER] Trying to stop PVServer (sending KILL) ...") + if not self.pvserverPop is None: + self.pvserverPop.poll() + if self.pvserverPop.returncode is None: + # Terminate if still running: + self.pvserverPop.terminate() + MESSAGE("[PVSERVER] KILL signal sent.") + return True + MESSAGE("[PVSERVER] Nothing to kill.") + return False + + def SetGUIConnected( self, isConnected ): + self.isGUIConnected = isConnected + + def GetGUIConnected( self ): + return self.isGUIConnected + + + \ No newline at end of file diff --git a/src/PVServerService/ENGINE/PVSERVER_utils.py b/src/PVServerService/ENGINE/PVSERVER_utils.py new file mode 100644 index 000000000..1a2b048a5 --- /dev/null +++ b/src/PVServerService/ENGINE/PVSERVER_utils.py @@ -0,0 +1,93 @@ +# Copyright (C) 2007-2015 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Adrien BRUNETON (CEA) +# + +from omniORB import CORBA +from SALOME_NamingServicePy import SALOME_NamingServicePy_i +import SALOMEDS + +from PVServer_ServiceLoader import PVServer_ServiceLoader +import PVSERVER_ORB + +### +# Get verbose level +### +__verbose__ = None +def verbose(): + import os + global __verbose__ + if __verbose__ is None: + try: + __verbose__ = int( os.getenv( 'SALOME_VERBOSE', 0 ) ) + except: + __verbose__ = 0 + pass + pass + return __verbose__ + +### +# Get ORB reference +### +__orb__ = None +def getORB(): + global __orb__ + if __orb__ is None: + __orb__ = CORBA.ORB_init( [''], CORBA.ORB_ID ) + pass + return __orb__ + +### +# Get naming service instance +### +__naming_service__ = None +def getNS(): + global __naming_service__ + if __naming_service__ is None: + __naming_service__ = SALOME_NamingServicePy_i( getORB() ) + pass + return __naming_service__ + +### +# Get PVSERVER service +### +__service__ = None +__serviceLoader__ = None +def getService(): + global __service__, __serviceLoader__ + containerName = "FactoryServer" + if __serviceLoader__ is None: + __serviceLoader__ = PVServer_ServiceLoader() + if __service__ is None: + import PVSERVER + ior = __serviceLoader__.findOrLoadService(containerName) + obj = getORB().string_to_object( ior ) + __service__ = obj._narrow(PVSERVER.PVSERVER) + pass + return __service__ + +### +# Get PVSERVER engine IOR +### +def getServiceIOR(): + IOR = "" + if getORB() and getService(): + IOR = getORB().object_to_string( getService() ) + pass + return IOR diff --git a/src/PVServerService/PVServerService.h b/src/PVServerService/PVServerService.h new file mode 100644 index 000000000..545e12312 --- /dev/null +++ b/src/PVServerService/PVServerService.h @@ -0,0 +1,33 @@ +// Copyright (C) 2010-2015 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef PVSERVERSERVICE_H +#define PVSERVERSERVICE_H + +#ifdef WIN32 +#if defined PVServerService_EXPORTS +#define PVSERVERSERVICE_EXPORT __declspec(dllexport) +#else +#define PVSERVERSERVICE_EXPORT __declspec(dllimport) +#endif +#else +#define PVSERVERSERVICE_EXPORT +#endif + +#endif //PVSERVERSERVICE_H diff --git a/src/PVViewer/PVViewer_EngineWrapper.cxx b/src/PVServerService/PVServer_ServiceWrapper.cxx similarity index 56% rename from src/PVViewer/PVViewer_EngineWrapper.cxx rename to src/PVServerService/PVServer_ServiceWrapper.cxx index e9c8abd8b..f086ba207 100644 --- a/src/PVViewer/PVViewer_EngineWrapper.cxx +++ b/src/PVServerService/PVServer_ServiceWrapper.cxx @@ -18,53 +18,59 @@ // // Author: Adrien Bruneton (CEA) -#include "PVViewer_EngineWrapper.h" +#include "PVServer_ServiceWrapper.h" #include -#include #include -class PVViewer_EngineWrapper::Private +class PVServer_ServiceWrapper::Private { public: - PyObjWrapper pvserverEngine; + // Borrowed reference to the Python object representing the service + PyObject* pvserverService; }; -PVViewer_EngineWrapper * PVViewer_EngineWrapper::instance = NULL; +PVServer_ServiceWrapper * PVServer_ServiceWrapper::instance = NULL; -PVViewer_EngineWrapper * PVViewer_EngineWrapper::GetInstance() +PVServer_ServiceWrapper * PVServer_ServiceWrapper::GetInstance() { if (!instance) - instance = new PVViewer_EngineWrapper(); + instance = new PVServer_ServiceWrapper(); return instance; } -PVViewer_EngineWrapper::PVViewer_EngineWrapper() +PVServer_ServiceWrapper::PVServer_ServiceWrapper() { myData = new Private; PyLockWrapper lock; - const char* code = "import PVSERVER_utils as pa;__enginePVSERVER=pa.getEngine()"; - int ret = PyRun_SimpleString(const_cast(code)); +#ifdef GUI_DISABLE_CORBA + const char* code = "import PVSERVER_impl as pi;__servicePVSERVER=pi.PVSERVER_Impl()"; +#else + const char* code = "import PVSERVER_utils as pa;__servicePVSERVER=pa.getService()"; +#endif + int ret = PyRun_SimpleString(const_cast(code)); if (ret == -1) - throw SALOME_Exception("Unable to retrieve PVSERVER engine!"); + throw SALOME_Exception("Unable to retrieve PVSERVER service!"); // Now get the reference to __engine and save the pointer. + // All the calls below returns *borrowed* references PyObject* main_module = PyImport_AddModule((char*)"__main__"); PyObject* global_dict = PyModule_GetDict(main_module); - PyObjWrapper tmp(PyDict_GetItemString(global_dict, "__enginePVSERVER")); - myData->pvserverEngine = tmp; + PyObject* tmp = PyDict_GetItemString(global_dict, "__servicePVSERVER"); + myData->pvserverService = tmp; } -PVViewer_EngineWrapper::~PVViewer_EngineWrapper() +PVServer_ServiceWrapper::~PVServer_ServiceWrapper() { + StopPVServer(); delete myData; } -bool PVViewer_EngineWrapper::GetGUIConnected() +bool PVServer_ServiceWrapper::GetGUIConnected() { PyLockWrapper lock; - PyObjWrapper obj(PyObject_CallMethod(myData->pvserverEngine, (char*)("GetGUIConnected"), NULL)); + PyObjWrapper obj(PyObject_CallMethod(myData->pvserverService, (char*)("GetGUIConnected"), NULL)); if (!obj) { PyErr_Print(); @@ -73,11 +79,11 @@ bool PVViewer_EngineWrapper::GetGUIConnected() return PyObject_IsTrue(obj); } -void PVViewer_EngineWrapper::SetGUIConnected(bool isConnected) +void PVServer_ServiceWrapper::SetGUIConnected(bool isConnected) { PyLockWrapper lock; - PyObjWrapper obj(PyObject_CallMethod(myData->pvserverEngine, (char*)("SetGUIConnected"), + PyObjWrapper obj(PyObject_CallMethod(myData->pvserverService, (char*)("SetGUIConnected"), (char *)"i", (int)isConnected ) ); if (!obj) { @@ -86,29 +92,29 @@ void PVViewer_EngineWrapper::SetGUIConnected(bool isConnected) } } -std::string PVViewer_EngineWrapper::FindOrStartPVServer(int port) +std::string PVServer_ServiceWrapper::FindOrStartPVServer(int port) { PyLockWrapper lock; - PyObjWrapper obj(PyObject_CallMethod(myData->pvserverEngine, (char*)("FindOrStartPVServer"), + PyObjWrapper obj(PyObject_CallMethod(myData->pvserverService, (char*)("FindOrStartPVServer"), (char *)"i", port ) ); if (!obj) { PyErr_Print(); throw SALOME_Exception("Unable to invoke PVSERVER service!"); } - char * s = PyString_AsString(obj); - - return std::string(s); + return std::string(PyString_AsString(obj)); } -void PVViewer_EngineWrapper::PutPythonTraceStringToEngine(const char * str) + +bool PVServer_ServiceWrapper::StopPVServer() { PyLockWrapper lock; - PyObjWrapper obj(PyObject_CallMethod(myData->pvserverEngine, (char*)("PutPythonTraceStringToEngine"), - (char *)"s", str) ); + PyObjWrapper obj(PyObject_CallMethod(myData->pvserverService, (char*)("StopPVServer"), NULL )); if (!obj) { PyErr_Print(); throw SALOME_Exception("Unable to invoke PVSERVER service!"); } + return PyObject_IsTrue(obj); } + diff --git a/src/PVViewer/PVViewer_EngineWrapper.h b/src/PVServerService/PVServer_ServiceWrapper.h similarity index 77% rename from src/PVViewer/PVViewer_EngineWrapper.h rename to src/PVServerService/PVServer_ServiceWrapper.h index 6ce74f2fd..13489c2b9 100644 --- a/src/PVViewer/PVViewer_EngineWrapper.h +++ b/src/PVServerService/PVServer_ServiceWrapper.h @@ -18,10 +18,10 @@ // // Author: Adrien Bruneton (CEA) -#ifndef PVVIEWERENGINEWRAPPER_H_ -#define PVVIEWERENGINEWRAPPER_H_ +#ifndef PVSERVERSERVICEWRAPPER_H_ +#define PVSERVERSERVICEWRAPPER_H_ -#include "PVViewer.h" +#include "PVServerService.h" #include @@ -29,24 +29,24 @@ * Class facilitating the access to the PARAVIS engine without having to link * to it. Documentation of the method is found in the PARAVIS module (in the idl directory). */ -class PVVIEWER_EXPORT PVViewer_EngineWrapper +class PVSERVERSERVICE_EXPORT PVServer_ServiceWrapper { class Private; public: //! Returns the unique instance of the engine. - static PVViewer_EngineWrapper* GetInstance(); + static PVServer_ServiceWrapper* GetInstance(); bool GetGUIConnected(); void SetGUIConnected(bool isConnected); std::string FindOrStartPVServer(int port); - void PutPythonTraceStringToEngine(const char*); + bool StopPVServer(); private: - PVViewer_EngineWrapper(); - virtual ~PVViewer_EngineWrapper(); + PVServer_ServiceWrapper(); + virtual ~PVServer_ServiceWrapper(); - static PVViewer_EngineWrapper* instance; + static PVServer_ServiceWrapper* instance; Private* myData; }; -#endif /* PVVIEWERENGINEWRAPPER_H_ */ +#endif /* PVSERVERSERVICEWRAPPER_H_ */ diff --git a/src/PVServerService/ServiceLoader/CMakeLists.txt b/src/PVServerService/ServiceLoader/CMakeLists.txt new file mode 100644 index 000000000..35c4f558e --- /dev/null +++ b/src/PVServerService/ServiceLoader/CMakeLists.txt @@ -0,0 +1,69 @@ +# Copyright (C) 2010-2015 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +INCLUDE(${SWIG_USE_FILE}) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${OMNIORB_INCLUDE_DIR} + ${KERNEL_INCLUDE_DIRS} + ) + +ADD_DEFINITIONS( + ${KERNEL_DEFINITIONS} + ) + +SET(_link_LIBRARIES + ${KERNEL_OpUtil} # class SALOME_Exception + ${KERNEL_SalomeContainer} + ${KERNEL_SalomeNS} + ${KERNEL_SalomeLifeCycleCORBA} + ) + +# --- headers --- +SET(_HEADERS + PVServer_ServiceLoader.h +) + +# --- sources --- +SET(_SOURCES + PVServer_ServiceLoader.cxx + ) + +SET(_SWIG + PVServer_ServiceLoader.i + ) + +# --- rules --- +ADD_LIBRARY(PVServerServiceLoader ${_SOURCES}) +TARGET_LINK_LIBRARIES(PVServerServiceLoader ${_link_LIBRARIES}) +INSTALL(TARGETS PVServerServiceLoader EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) + +# --- SWIG part --- +SET_SOURCE_FILES_PROPERTIES(${_SWIG} PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(${_SWIG} PROPERTIES SWIG_DEFINITIONS "-shadow") +SWIG_ADD_MODULE(PVServer_ServiceLoader python ${_SWIG}) +SWIG_LINK_LIBRARIES(PVServer_ServiceLoader ${PYTHON_LIBRARIES} PVServerServiceLoader) + +INSTALL(TARGETS ${SWIG_MODULE_PVServer_ServiceLoader_REAL_NAME} EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_PYTHON}) +SALOME_INSTALL_SCRIPTS(${CMAKE_CURRENT_BINARY_DIR}/PVServer_ServiceLoader.py ${SALOME_INSTALL_PYTHON}) + +# --- header installation --- +INSTALL(FILES ${_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.cxx b/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.cxx new file mode 100644 index 000000000..6bfe12307 --- /dev/null +++ b/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.cxx @@ -0,0 +1,104 @@ +// Copyright (C) 2010-2015 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author: Adrien Bruneton (CEA) + +#include "PVServer_ServiceLoader.h" +#include "PVServer_ServiceWrapper.h" + +#include +#include +#include // MESSAGE() macro + +PVServer_ServiceLoader::PVServer_ServiceLoader(): + _lcc(0) +{ + _lcc = new SALOME_LifeCycleCORBA(); + _ns = _lcc->namingService(); + _cm = _lcc->getContainerManager(); + _orb = _lcc->orb(); + +} + +PVServer_ServiceLoader::~PVServer_ServiceLoader() +{ + if (_lcc) + delete _lcc; + _lcc = 0; +} + +std::string PVServer_ServiceLoader::findOrLoadService(const char * containerName) +{ + std::string ior = findService(containerName); + if (ior == "") + ior = loadService(containerName); + return ior; +} + +std::string PVServer_ServiceLoader::findService(const char * containerName) +{ + std::string path = std::string(containerName) + "/PVSERVER"; + CORBA::Object_ptr obj = _ns->Resolve(path.c_str()); + if(!CORBA::is_nil(obj)) + { + MESSAGE("PVServer_ServiceLoader::findService(): Service found! "); + char * ior = _orb->object_to_string(obj); + return std::string(ior); + } + else + { + MESSAGE("PVServer_ServiceLoader::findService(): Service NOT found! "); + return std::string(""); + } + +} + +std::string PVServer_ServiceLoader::loadService(const char * containerName) +{ + // Get the requested container + Engines::ContainerParameters params; + params.container_name = CORBA::string_dup(containerName); + params.isMPI = false; + params.mode = "getorstart"; + Engines::Container_ptr contain = _cm->GiveContainer(params); + + if (!CORBA::is_nil(contain)) + { + char * reason; + char * ior = contain->create_python_service_instance("PVSERVER", reason); + std::string reas(reason); + CORBA::string_free(reason); + if (reas != "") + { + MESSAGE("PVServer_ServiceLoader::loadService(): Python service instance could not be created! "); + MESSAGE("PVServer_ServiceLoader::loadService(): " << reas); + return std::string(""); + } + else + { + MESSAGE("PVServer_ServiceLoader::loadService(): Container and service loaded! "); + return std::string(ior); + } + } + else + { + MESSAGE("PVServer_ServiceLoader::loadService(): Container could not be retrieved! "); + return std::string(""); + } +} + diff --git a/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.h b/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.h new file mode 100644 index 000000000..7a443eb3d --- /dev/null +++ b/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.h @@ -0,0 +1,50 @@ +// Copyright (C) 2010-2015 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author: Adrien Bruneton (CEA) + +#ifndef PVSERVERSERVICELOADER_H_ +#define PVSERVERSERVICELOADER_H_ + +#include "PVServerService.h" + +#include + +class SALOME_LifeCycleCORBA; +class SALOME_NamingService; + +class PVSERVERSERVICE_EXPORT PVServer_ServiceLoader +{ +public: + PVServer_ServiceLoader(); + virtual ~PVServer_ServiceLoader(); + + //! Get the IOR of the CORBA service handling the PVServer + std::string findOrLoadService(const char * containerName); + +private: + std::string findService(const char * containerName); + std::string loadService(const char * containerName); + + SALOME_LifeCycleCORBA * _lcc; + CORBA::ORB_ptr _orb; + SALOME_NamingService * _ns; + Engines::ContainerManager_ptr _cm; +}; + +#endif /* PVSERVERSERVICELOADER_H_ */ diff --git a/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.i b/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.i new file mode 100644 index 000000000..244962d13 --- /dev/null +++ b/src/PVServerService/ServiceLoader/PVServer_ServiceLoader.i @@ -0,0 +1,14 @@ +%module PVServer_ServiceLoader + +%{ + #include "PVServer_ServiceLoader.h" +%} + +%include + +class PVServer_ServiceLoader +{ +public: + //! Get the IOR of the CORBA service handling the PVServer + std::string findOrLoadService(const char * containerName); +}; diff --git a/src/PVViewer/CMakeLists.txt b/src/PVViewer/CMakeLists.txt index e7f57b58a..65d5f73b5 100644 --- a/src/PVViewer/CMakeLists.txt +++ b/src/PVViewer/CMakeLists.txt @@ -30,6 +30,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/Qtx ${PROJECT_SOURCE_DIR}/src/Event ${PROJECT_SOURCE_DIR}/src/PyInterp + ${PROJECT_SOURCE_DIR}/src/PVServerService ${CMAKE_SOURCE_DIR}/src/LogWindow ) @@ -44,6 +45,7 @@ SET(_link_LIBRARIES PyInterp suit Event + PVServerService pqApplicationComponents vtkRenderingFreeTypeOpenGL ) @@ -63,7 +65,6 @@ SET(_moc_HEADERS SET(_other_HEADERS PVViewer.h PVViewer_LogWindowAdapter.h - PVViewer_EngineWrapper.h PVViewer_Core.h ) # header files / to install @@ -92,7 +93,6 @@ SET(_other_SOURCES PVViewer_LogWindowAdapter.cxx PVViewer_Behaviors.cxx PVViewer_GUIElements.cxx - PVViewer_EngineWrapper.cxx PVViewer_Core.cxx ) diff --git a/src/PVViewer/PVViewer_Core.cxx b/src/PVViewer/PVViewer_Core.cxx index 93750ddec..5627c517a 100644 --- a/src/PVViewer/PVViewer_Core.cxx +++ b/src/PVViewer/PVViewer_Core.cxx @@ -23,7 +23,6 @@ #include "PVViewer_LogWindowAdapter.h" #include "PVViewer_GUIElements.h" #include "PVViewer_Behaviors.h" -#include "PVViewer_EngineWrapper.h" #include "PVViewer_Core.h" #include diff --git a/src/PVViewer/PVViewer_Core.h b/src/PVViewer/PVViewer_Core.h index 8ea1c2435..aef251cc0 100644 --- a/src/PVViewer/PVViewer_Core.h +++ b/src/PVViewer/PVViewer_Core.h @@ -25,7 +25,7 @@ #include -class PVViewer_EngineWrapper; +class PVServer_ServiceWrapper; class PVViewer_Behaviors; class LogWindow; class QMainWindow; diff --git a/src/PVViewer/PVViewer_ViewManager.cxx b/src/PVViewer/PVViewer_ViewManager.cxx index b630ce501..f08ffa086 100644 --- a/src/PVViewer/PVViewer_ViewManager.cxx +++ b/src/PVViewer/PVViewer_ViewManager.cxx @@ -23,7 +23,7 @@ #include "PVViewer_ViewModel.h" #include "PVViewer_GUIElements.h" #include "PVViewer_Core.h" -#include "PVViewer_EngineWrapper.h" +#include "PVServer_ServiceWrapper.h" #include @@ -56,9 +56,9 @@ PVViewer_ViewManager::PVViewer_ViewManager( SUIT_Study* study, SUIT_Desktop* des } -PVViewer_EngineWrapper * PVViewer_ViewManager::GetEngine() +PVServer_ServiceWrapper * PVViewer_ViewManager::GetService() { - return PVViewer_EngineWrapper::GetInstance(); + return PVServer_ServiceWrapper::GetInstance(); } QString PVViewer_ViewManager::GetPVConfigPath() @@ -82,7 +82,7 @@ bool PVViewer_ViewManager::ConnectToExternalPVServer(QMainWindow* aDesktop) return false; } - if (GetEngine()->GetGUIConnected()) + if (GetService()->GetGUIConnected()) { // Should never be there as the above should already tell us that we are connected. std::stringstream msg2; @@ -104,7 +104,7 @@ bool PVViewer_ViewManager::ConnectToExternalPVServer(QMainWindow* aDesktop) else { // Get the URL from the engine (possibly starting the pvserver) - serverUrl = GetEngine()->FindOrStartPVServer(0); // take the first free port + serverUrl = GetService()->FindOrStartPVServer(0); // take the first free port } msg << "connectToExternalPVServer(): Trying to connect to the external PVServer '" << serverUrl << "' ..."; @@ -123,7 +123,7 @@ bool PVViewer_ViewManager::ConnectToExternalPVServer(QMainWindow* aDesktop) else { MESSAGE("connectToExternalPVServer(): Connected!"); - GetEngine()->SetGUIConnected(true); + GetService()->SetGUIConnected(true); } return true; } diff --git a/src/PVViewer/PVViewer_ViewManager.h b/src/PVViewer/PVViewer_ViewManager.h index 416b6b953..7c3bf2484 100644 --- a/src/PVViewer/PVViewer_ViewManager.h +++ b/src/PVViewer/PVViewer_ViewManager.h @@ -29,7 +29,7 @@ class SUIT_Desktop; class SUIT_Study; class SUIT_ViewWindow; class LogWindow; -class PVViewer_EngineWrapper; +class PVServer_ServiceWrapper; class QMainWindow; class PVVIEWER_EXPORT PVViewer_ViewManager : public SUIT_ViewManager @@ -41,7 +41,7 @@ public: ~PVViewer_ViewManager() {} //! Get the CORBA engine wrapper. - static PVViewer_EngineWrapper * GetEngine(); + static PVServer_ServiceWrapper * GetService(); //! Get PVViewer configuration path as stored by SALOME's resource manager: static QString GetPVConfigPath(); -- 2.30.2