Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / runtime / SalomeContainer.cxx
1 //#define REFCNT
2 #ifdef REFCNT
3 #define private public
4 #define protected public
5 #include <omniORB4/CORBA.h>
6 #include <omniORB4/internal/typecode.h>
7 #endif
8
9 #include "RuntimeSALOME.hxx"
10 #include "SalomeContainer.hxx"
11 #include "SalomeComponent.hxx"
12
13 #include "SALOME_NamingService.hxx"
14 #include "SALOME_LifeCycleCORBA.hxx"
15 #include "SALOME_ContainerManager.hxx"
16 #include "OpUtil.hxx"
17
18 #include <sstream>
19 #include <iostream>
20
21 //#define _DEVDEBUG_
22 #include "YacsTrace.hxx"
23
24 using namespace YACS::ENGINE;
25 using namespace std;
26
27 SalomeContainer::SalomeContainer():_trueCont(Engines::Container::_nil())
28 {
29   /* Init MachinesParameters */
30   _params.container_name = "";
31   _params.hostname = "";
32   _params.OS = "";
33   _params.mem_mb = 0;
34   _params.cpu_clock = 0;
35   _params.nb_proc_per_node = 0;
36   _params.nb_node = 0;
37   _params.isMPI = false;
38   _params.parallelLib = "";
39   _params.nb_component_nodes = 0;
40 }
41
42 SalomeContainer::SalomeContainer(const SalomeContainer& other):Container(other),_trueCont(Engines::Container::_nil())
43 {
44   _params.container_name = CORBA::string_dup(other._params.container_name);
45   _params.hostname = CORBA::string_dup(other._params.hostname);
46   _params.OS = CORBA::string_dup(other._params.OS);
47   _params.mem_mb = other._params.mem_mb;
48   _params.cpu_clock = other._params.cpu_clock;
49   _params.nb_proc_per_node = other._params.nb_proc_per_node;
50   _params.nb_node = other._params.nb_node;
51   _params.isMPI = other._params.isMPI;
52   _params.parallelLib = CORBA::string_dup(other._params.parallelLib);
53   _params.nb_component_nodes = other._params.nb_component_nodes;
54   _params.workingdir= CORBA::string_dup(other._params.workingdir);
55 }
56
57 SalomeContainer::~SalomeContainer()
58 {
59 }
60
61 void SalomeContainer::lock()
62 {
63   _mutex.lock();
64 }
65
66 void SalomeContainer::unLock()
67 {
68   _mutex.unlock();
69 }
70
71 bool SalomeContainer::isAlreadyStarted() const
72 {
73   if(CORBA::is_nil(_trueCont))
74     return false;
75   else
76     return true;
77 }
78
79 void SalomeContainer::start() throw (Exception)
80 {
81   CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
82   SALOME_NamingService ns;
83   try
84     {
85       ns.init_orb(orb);
86     }
87   catch(SALOME_Exception& e)
88     {
89       throw Exception("SalomeContainer::start : Unable to contact the SALOME Naming Service");
90     }
91   CORBA::Object_var obj=ns.Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS);
92   Engines::ContainerManager_var contManager=Engines::ContainerManager::_narrow(obj);
93
94   std::string str(_params.container_name);
95   //If a container_name is given try to find an already existing container in naming service
96   //If not found start a new container with the given parameters
97   if (str != "")
98     {
99       std::string machine(_params.hostname);
100       if(machine == "" || machine == "localhost")
101         machine=GetHostname();
102       std::string ContainerNameInNS=ns.BuildContainerNameForNS(_params,machine.c_str());
103       obj=ns.Resolve(ContainerNameInNS.c_str());
104       if(!CORBA::is_nil(obj))
105         {
106           std::cerr << "Container already exists: " << ContainerNameInNS << std::endl;
107           _trueCont=Engines::Container::_narrow(obj);
108           return;
109         }
110     }
111
112   if (str == "") 
113     {
114       std::ostringstream stream;
115       stream << (void *)(this);
116       _params.container_name=CORBA::string_dup(stream.str().c_str());
117     }
118   Engines::CompoList compolist;
119   compolist.length(_componentNames.size());
120   std::vector<std::string>::iterator iter;
121   for(CORBA::ULong i=0; i < _componentNames.size();i++)
122     {
123       compolist[i]=CORBA::string_dup(_componentNames[i].c_str());
124     }
125
126   try
127     { 
128       // --- GiveContainer is used in batch mode to retreive launched containers,
129       //     and is equivalent to StartContainer when not in batch.
130       std::string policy=getProperty("policy");
131       if(policy=="best")
132         _trueCont=contManager->GiveContainer(_params,Engines::P_BEST,compolist);
133       else if(policy=="first")
134         _trueCont=contManager->GiveContainer(_params,Engines::P_FIRST,compolist);
135       else
136         _trueCont=contManager->GiveContainer(_params,Engines::P_CYCL,compolist);
137     }
138   catch(CORBA::COMM_FAILURE&)
139     {
140       throw Exception("SalomeContainer::start : Unable to launch container in Salome : CORBA Comm failure detected");
141     }
142   catch(CORBA::Exception&)
143     {
144       throw Exception("SalomeContainer::start : Unable to launch container in Salome : Unexpected CORBA failure detected");
145     }
146   if(CORBA::is_nil(_trueCont))
147     throw Exception("SalomeContainer::start : Unable to launch container in Salome. Check your CatalogResources.xml file");
148
149   CORBA::String_var containerName=_trueCont->name();
150   CORBA::String_var hostName=_trueCont->getHostName();
151   std::cerr << "SalomeContainer launched : " << containerName << " " << hostName << " " << _trueCont->getPID() << std::endl;
152
153 #ifdef REFCNT
154     DEBTRACE(_trueCont->_PR_getobj()->pd_refCount );
155 #endif
156 }
157
158 Container *SalomeContainer::clone() const
159 {
160   if(_isAttachedOnCloning)
161     {
162       incrRef();
163       return (Container*) (this);
164     }
165   else
166     return new SalomeContainer(*this);
167 }
168
169 std::string SalomeContainer::getPlacementId() const
170 {
171   if(isAlreadyStarted())
172     {
173       const char *what="/";
174       char *corbaStr=_trueCont->name();
175       string ret(corbaStr);
176       CORBA::string_free(corbaStr);
177       //Salome FOREVER ...
178       std::string::size_type i=ret.find_first_of(what,0);
179       i=ret.find_first_of(what, i==std::string::npos ? i:i+1);
180       if(i!=std::string::npos)
181         return ret.substr(i+1);
182       return ret;
183     }
184   else
185     return "Not placed yet !!!";
186 }
187
188 void SalomeContainer::checkCapabilityToDealWith(const ComponentInstance *inst) const throw (Exception)
189 {
190   if(inst->getKind()!=SalomeComponent::KIND)
191     throw Exception("SalomeContainer::checkCapabilityToDealWith : SalomeContainer is not able to deal with this type of ComponentInstance.");
192 }
193
194 void SalomeContainer::setProperty(const std::string& name, const std::string& value)
195 {
196   DEBTRACE("SalomeContainer::setProperty : " << name << " ; " << value);
197   
198   if (name == "container_name")
199     _params.container_name = CORBA::string_dup(value.c_str());
200   else if (name == "hostname")
201     _params.hostname = CORBA::string_dup(value.c_str());
202   else if (name == "OS")
203     _params.OS = CORBA::string_dup(value.c_str());
204   else if (name == "parallelLib")
205     _params.parallelLib = CORBA::string_dup(value.c_str());
206   else if (name == "workingdir")
207     _params.workingdir = CORBA::string_dup(value.c_str());
208   else if (name == "isMPI")
209     {
210       if (value == "true")
211         _params.isMPI = true;
212       else if (value == "false")
213         _params.isMPI = false;
214       else 
215         throw Exception("SalomeContainer::SetProperty : params.isMPI value not correct : " + value);
216     }
217   else if (name == "mem_mb")
218     {
219       std::istringstream iss(value);
220       if (!(iss >> _params.mem_mb))
221         throw Exception("salomecontainer::setproperty : params.mem_mb value not correct : " + value);
222     }
223   else if (name == "cpu_clock")
224     {
225       std::istringstream iss(value);
226       if (!(iss >> _params.cpu_clock))
227         throw Exception("salomecontainer::setproperty : params.cpu_clock value not correct : " + value);
228     }
229   else if (name == "nb_proc_per_node")
230     {
231       std::istringstream iss(value);
232       if (!(iss >> _params.nb_proc_per_node))
233         throw Exception("salomecontainer::setproperty : params.nb_proc_per_node value not correct : " + value);
234     }
235   else if (name == "nb_node")
236     {
237       std::istringstream iss(value);
238       if (!(iss >> _params.nb_node))
239         throw Exception("salomecontainer::setproperty : params.nb_node value not correct : " + value);
240     }
241   else if (name == "nb_component_nodes")
242     {
243       std::istringstream iss(value);
244       if (!(iss >> _params.nb_component_nodes))
245         throw Exception("salomecontainer::setproperty : params.nb_component_nodes value not correct : " + value);
246     }
247   Container::setProperty(name, value);
248 }
249
250 bool SalomeContainer::isAPaCOContainer() const
251 {
252   bool result = false;
253   string parallelLib(_params.parallelLib);
254   if (parallelLib != "")
255     result = true;
256   return result;
257 }
258
259 void SalomeContainer::addComponentName(std::string name)
260 {
261   _componentNames.push_back(name);
262 }