Salome HOME
CCAR: remove bug in FindOrLoad_Component
[modules/kernel.git] / src / LifeCycleCORBA / LifeCycleCORBA.py
1 #  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 #  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 #  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 #
6 #  This library is free software; you can redistribute it and/or
7 #  modify it under the terms of the GNU Lesser General Public
8 #  License as published by the Free Software Foundation; either
9 #  version 2.1 of the License.
10 #
11 #  This library is distributed in the hope that it will be useful,
12 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 #  Lesser General Public License for more details.
15 #
16 #  You should have received a copy of the GNU Lesser General Public
17 #  License along with this library; if not, write to the Free Software
18 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 #
20 #  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #
22 #  SALOME LifeCycleC RBA : implementation of containers and engines life cycle both in Python and C++
23 #  File   : LifeCycleCORBA.py
24 #  Author : Paul RASCLE, EDF
25 #  Module : SALOME
26 #  $Header$
27 #
28 import os
29 import sys
30 import time
31 import string
32 from omniORB import CORBA
33 import CosNaming
34 import Engines
35 reload(Engines)
36 import SALOME_ModuleCatalog
37
38 from SALOME_utilities import *
39 from Utils_Identity import getShortHostName
40 import Utils_Identity 
41 import Launchers
42
43 class LifeCycleCORBA:
44     _orb = None
45     _rootcontext = None
46     _containerRootContext = None
47     _catalog = None
48     
49     #-------------------------------------------------------------------------
50
51     def __init__(self, orb):
52         MESSAGE( "LifeCycleCORBA::__init__" )
53         self._orb = orb
54
55         obj = self._orb.resolve_initial_references("NameService")
56         self._rootContext = obj._narrow(CosNaming.NamingContext)
57
58         if self._rootContext is None:
59             MESSAGE( "Name Service Reference is invalid" )
60
61         name = [CosNaming.NameComponent("Containers","dir")]
62         try:
63             self._containerRootContext = self._rootContext.bind_new_context(name)
64
65         except CosNaming.NamingContext.AlreadyBound, ex:
66             MESSAGE( "/Containers.dir Context already exists" )
67             obj = self._rootContext.resolve(name)
68             self._containerRootContext = obj._narrow(CosNaming.NamingContext)
69             if self._containerRootContext is None:
70                 MESSAGE( "Containers.dir exists but it is not a NamingContext" )
71
72         name = [CosNaming.NameComponent("Kernel","dir"),
73                 CosNaming.NameComponent("ModulCatalog","object")]
74         try:
75             obj = self._rootContext.resolve(name)
76         except CosNaming.NamingContext.NotFound, ex:
77             MESSAGE( "/Kernel.dir/ModulCatalog.object not found in Naming Service" )
78
79         self._catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog)
80         if self._catalog is None:
81             MESSAGE( "/Kernel.dir/ModulCatalog.object exists but is not a ModulCatalog" )
82
83         name = [CosNaming.NameComponent("ContainerManager","object")]
84         try:
85             obj = self._rootContext.resolve(name)
86         except CosNaming.NamingContext.NotFound, ex:
87             MESSAGE( "ContainerManager.object not found in Naming Service" )
88         self._contManager = obj._narrow(Engines.ContainerManager)
89         if self._contManager is None:
90             MESSAGE( "ContainerManager.object exists but is not a ContainerManager")
91
92     #-------------------------------------------------------------------------
93
94     def ContainerName(self, containerName):
95         theComputer = ""
96         try:
97             theComputer , theContainer = containerName.split('/')
98         except:
99             theComputer = ""
100             theContainer = containerName
101
102         if theComputer in ("","localhost") :
103             theComputer = getShortHostName()
104
105         MESSAGE( theComputer + theContainer )
106         return theComputer,theContainer
107
108     #-------------------------------------------------------------------------
109
110     def ComputerPath(self, ComputerName ):
111         try:
112             #path = self._catalog.GetPathPrefix( ComputerName )
113             path = os.getenv("KERNEL_ROOT_DIR") + "/bin/salome/"
114         except SALOME_ModuleCatalog.NotFound, ex:
115             path = ""
116         return path
117
118     #-------------------------------------------------------------------------
119
120     def FindContainer(self, containerName):
121         theComputer,theContainer = self.ContainerName( containerName )
122         name = [CosNaming.NameComponent(theComputer,"dir"),
123                 CosNaming.NameComponent(theContainer,"object")]
124         obj = None
125         try:
126             obj = self._containerRootContext.resolve(name)
127             MESSAGE( containerName + ".object found in Naming Service" )
128
129         except CosNaming.NamingContext.NotFound, ex:
130             MESSAGE( containerName + ".object not found in Naming Service" )
131
132         if obj is None:
133             container = None
134         else:
135             container = obj._narrow(Engines.Container)
136             if container is None:
137                 MESSAGE( containerName + ".object exists but is not a Container" )
138         return container
139     
140     #-------------------------------------------------------------------------
141
142     def FindComponent(self,containerName,componentName,listOfMachines):
143         if containerName!="":
144             machinesOK=[]
145             for i in range(len(listOfMachines)):
146                 currentMachine=listOfMachines[i]
147                 componentNameForNS= [CosNaming.NameComponent(currentMachine,"dir"),
148                                      CosNaming.NameComponent(containerName,"dir"),
149                                      CosNaming.NameComponent(componentName,"object")]
150                 obj=None
151                 try:
152                     obj = self._containerRootContext.resolve(componentNameForNS)
153                 except CosNaming.NamingContext.NotFound, ex:
154                     MESSAGE( "component " + componentName + " not found on machine " + currentMachine + " , trying to load" )
155                     pass
156                 if obj is not None:
157                     machinesOK.append(currentMachine)
158                     pass
159                 pass
160             if len(machinesOK)!=0:
161                 bestMachine=self._contManager.FindFirst(machinesOK)
162                 componentNameForNS= [CosNaming.NameComponent(bestMachine,"dir"),
163                                      CosNaming.NameComponent(containerName,"dir"),
164                                      CosNaming.NameComponent(componentName,"object")]
165                 obj=None
166                 try:
167                     obj = self._containerRootContext.resolve(componentNameForNS)
168                 except:
169                     pass
170                 if obj is not None:
171                     return obj._narrow(Engines.Component)
172                 else:
173                     MESSAGE( "Big problem !!!")
174                     return None
175             else:
176                 return None
177         else:
178             bestMachine=self._contManager.FindFirst(listOfMachines)
179             MESSAGE("Not implemented yet ...")
180             return None
181         pass
182
183     #-------------------------------------------------------------------------
184
185     def setLauncher(self,name):
186         """Change default launcher to the launcher identified by name
187
188            See module Launchers.py
189         """
190         Launchers.setLauncher(name)
191
192     #-------------------------------------------------------------------------
193
194     def StartContainer(self, theComputer , theContainer ):
195         """Start a container on theComputer machine with theContainer name
196         """
197         # Get the Naming Service address
198         #
199         addr=self._orb.object_to_string(self._rootContext)
200         #
201         # If container name contains "Py" launch a Python Container
202         #
203         if theContainer.find('Py') == -1 :
204            CMD=['SALOME_Container',theContainer,'-ORBInitRef','NameService='+addr]
205         else:
206            CMD=['SALOME_ContainerPy.py',theContainer,'-ORBInitRef','NameService='+addr]
207         if theComputer in ("","localhost"):
208            theComputer=getShortHostName()
209         #
210         # Get the appropriate launcher and ask to launch
211         #
212         Launchers.getLauncher(theComputer).launch(theComputer,CMD)
213         #
214         # Wait until the container is registered in Naming Service
215         #
216         count =5 
217         aContainer=None
218         while aContainer is None and count > 0:
219             time.sleep(1)
220             count = count - 1
221             MESSAGE( str(count) + ". Waiting for " + theComputer + "/" + theContainer )
222             aContainer = self.FindContainer( theComputer + "/" + theContainer )
223         return aContainer
224
225     #-------------------------------------------------------------------------
226
227     def FindOrStartContainer(self, theComputer , theContainer ):
228         """Find or Start a container on theComputer machine with theContainer name
229         """
230         if theComputer in ("","localhost"):
231            theComputer=getShortHostName()
232         MESSAGE( "FindOrStartContainer: " + theComputer + theContainer )
233         aContainer = self.FindContainer( theComputer + "/" + theContainer )
234         if aContainer is None :
235             aContainer= self.StartContainer(theComputer , theContainer )
236         return aContainer
237             
238     #-------------------------------------------------------------------------
239
240     def LoadComponent(self,containerName,componentName,listOfMachine):
241         container=self._contManager.FindOrStartContainer(containerName,listOfMachine)
242         implementation="lib"+componentName+"Engine.so"
243         try:
244             component = container.load_impl(componentName, implementation)
245             MESSAGE( "component " + component._get_instanceName() + " launched !" )
246             return component
247         except:
248             MESSAGE( "component " + componentName + " NOT launched !" )
249             return None
250
251     #-------------------------------------------------------------------------
252     
253
254     def FindOrLoadComponent(self, containerName, componentName):
255         sp=containerName.split("/")
256         if len(sp)==1:
257             listOfMachine=[]
258             listOfMachine.append(getShortHostName())
259             comp=self.FindComponent(containerName,componentName,listOfMachine)
260             if comp is None:
261                 return self.LoadComponent(containerName,componentName,listOfMachine)
262             else:
263                 return comp
264             pass
265         else:
266             params= Engines.MachineParameters(sp[1],sp[0],"LINUX",0,0,0,0)
267             listOfMachine=self._contManager.GetFittingResources(params,componentName)
268             ret=self.FindComponent(sp[1],componentName,listOfMachine);
269             if ret is None:
270                 return self.LoadComponent(sp[1],componentName,listOfMachine)
271             else:
272                 return ret
273             pass
274