1 // Copyright (C) 2006-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "SalomeContainerTools.hxx"
21 #include "SALOME_LifeCycleCORBA.hxx"
22 #include "SALOME_NamingService.hxx"
23 #include "SALOME_ResourcesManager.hxx"
24 #include "SALOME_ContainerManager.hxx"
25 #include "Container.hxx"
27 #include "YacsTrace.hxx"
29 #include "ServiceNode.hxx"
30 #include "ComponentInstance.hxx"
31 #include "SalomeContainerHelper.hxx"
32 #include "RuntimeSALOME.hxx"
33 #include "Exception.hxx"
37 using namespace YACS::ENGINE;
39 SalomeContainerTools::SalomeContainerTools()
41 /* Init ContainerParameters */
42 SALOME_LifeCycleCORBA::preSet(_params);
45 SalomeContainerTools::SalomeContainerTools(const SalomeContainerTools& other):_params(other._params),_propertyMap(other._propertyMap)
49 void SalomeContainerTools::clearProperties()
52 _params=Engines::ContainerParameters();
55 std::string SalomeContainerTools::getProperty(const std::string& name) const
57 std::map<std::string,std::string>::const_iterator it(_propertyMap.find(name));
58 if(it!=_propertyMap.end())
64 void SalomeContainerTools::setProperty(const std::string& name, const std::string& value)
66 //DEBTRACE("SalomeContainer::setProperty : " << name << " ; " << value);
68 if (name == "container_name")
69 _params.container_name = CORBA::string_dup(value.c_str());
70 else if (name == "workingdir")
71 _params.workingdir = CORBA::string_dup(value.c_str());
72 else if (name == "nb_parallel_procs")
74 std::istringstream iss(value);
75 if (!(iss >> _params.nb_proc))
76 throw Exception("salomecontainer::setproperty : params.nb_proc value not correct : " + value);
78 else if (name == "isMPI")
82 else if (value == "false")
83 _params.isMPI = false;
85 throw Exception("SalomeContainer::setProperty : params.isMPI value not correct : " + value);
87 else if (name == "parallelLib")
88 _params.parallelLib = CORBA::string_dup(value.c_str());
91 else if (name == "name")
92 _params.resource_params.name = CORBA::string_dup(value.c_str());
93 else if (name == "hostname")
94 _params.resource_params.hostname = CORBA::string_dup(value.c_str());
95 else if (name == "OS")
96 _params.resource_params.OS = CORBA::string_dup(value.c_str());
97 else if (name == "nb_resource_procs")
99 std::istringstream iss(value);
100 if (!(iss >> _params.resource_params.nb_proc))
101 throw Exception("salomecontainer::setproperty : params.resource_params.nb_proc value not correct : " + value);
103 else if (name == "mem_mb")
105 std::istringstream iss(value);
106 if (!(iss >> _params.resource_params.mem_mb))
107 throw Exception("salomecontainer::setproperty : params.resource_params.mem_mb value not correct : " + value);
109 else if (name == "cpu_clock")
111 std::istringstream iss(value);
112 if (!(iss >> _params.resource_params.cpu_clock))
113 throw Exception("salomecontainer::setproperty : params.resource_params.cpu_clock value not correct : " + value);
115 else if (name == "nb_node")
117 std::istringstream iss(value);
118 if (!(iss >> _params.resource_params.nb_node))
119 throw Exception("salomecontainer::setproperty : params.nb_node value not correct : " + value);
121 else if (name == "nb_proc_per_node")
123 std::istringstream iss(value);
124 if (!(iss >> _params.resource_params.nb_proc_per_node))
125 throw Exception("salomecontainer::setproperty : params.nb_proc_per_node value not correct : " + value);
127 else if (name == "policy")
128 _params.resource_params.policy = CORBA::string_dup(value.c_str());
129 else if (name == "component_list")
131 std::string clean_value(value);
133 // Step 1: remove blanks
134 while(clean_value.find(" ") != std::string::npos)
135 clean_value = clean_value.erase(clean_value.find(" "), 1);
137 // Step 2: get values
138 while(!clean_value.empty())
140 std::string result("");
141 std::string::size_type loc = clean_value.find(",", 0);
142 if (loc != std::string::npos)
144 result = clean_value.substr(0, loc);
145 clean_value = clean_value.erase(0, loc+1);
149 result = clean_value;
152 if (result != "," && result != "")
154 addToComponentList(result);
159 else if (name == "resource_list")
161 std::string clean_value(value);
163 // Step 1: remove blanks
164 while(clean_value.find(" ") != std::string::npos)
165 clean_value = clean_value.erase(clean_value.find(" "), 1);
167 // Step 2: get values
168 while(!clean_value.empty())
170 std::string result("");
171 std::string::size_type loc = clean_value.find(",", 0);
172 if (loc != std::string::npos)
174 result = clean_value.substr(0, loc);
175 clean_value = clean_value.erase(0, loc+1);
179 result = clean_value;
182 if (result != "," && result != "")
184 addToResourceList(result);
189 _propertyMap[name]=value;
192 void SalomeContainerTools::addToComponentList(const std::string& name)
194 // Search if name is already in the list
195 for (CORBA::ULong i = 0; i < _params.resource_params.componentList.length(); i++)
197 std::string component_name = _params.resource_params.componentList[i].in();
198 if (component_name == name)
202 CORBA::ULong lgth = _params.resource_params.componentList.length();
203 _params.resource_params.componentList.length(lgth + 1);
204 _params.resource_params.componentList[lgth] = CORBA::string_dup(name.c_str());
207 void SalomeContainerTools::addToResourceList(const std::string& name)
209 // Search if name is already in the list
210 for (CORBA::ULong i = 0; i < _params.resource_params.resList.length(); i++)
212 std::string component_name = _params.resource_params.resList[i].in();
213 if (component_name == name)
217 CORBA::ULong lgth = _params.resource_params.resList.length();
218 _params.resource_params.resList.length(lgth + 1);
219 _params.resource_params.resList[lgth] = CORBA::string_dup(name.c_str());
222 std::string SalomeContainerTools::getContainerName() const
224 return std::string(_params.container_name);
227 void SalomeContainerTools::setContainerName(const std::string& name)
229 SetContainerNameOf(_params,name);
232 std::string SalomeContainerTools::getNotNullContainerName(const Container *contPtr, bool& isEmpty) const
235 std::string name(_params.container_name);
243 //give a almost unique name to the container : Pid_Name_Addr
244 std::ostringstream stream;
247 stream << contPtr->getName();
249 stream << (const void *)contPtr;
254 std::string SalomeContainerTools::getHostName() const
256 return std::string(_params.resource_params.hostname);
259 void SalomeContainerTools::SetContainerNameOf(Engines::ContainerParameters& params, const std::string& name)
261 params.container_name=CORBA::string_dup(name.c_str());
264 std::map<std::string,std::string> SalomeContainerTools::getResourceProperties(const std::string& name) const
266 std::map<std::string,std::string> properties;
268 YACS::ENGINE::RuntimeSALOME* runTime = YACS::ENGINE::getSALOMERuntime();
269 CORBA::ORB_ptr orb = runTime->getOrb();
270 if (!orb) return properties;
271 SALOME_NamingService namingService(orb);
272 SALOME_LifeCycleCORBA lcc(&namingService);
273 CORBA::Object_var obj = namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS);
274 if (CORBA::is_nil(obj))
276 Engines::ResourcesManager_var resManager = Engines::ResourcesManager::_narrow(obj);
277 if (CORBA::is_nil(resManager))
280 std::ostringstream value;
281 Engines::ResourceDefinition_var resource_definition = resManager->GetResourceDefinition(name.c_str());
282 properties["hostname"]=resource_definition->hostname.in();
283 properties["OS"]=resource_definition->OS.in();
284 value.str(""); value << resource_definition->mem_mb;
285 properties["mem_mb"]=value.str();
286 value.str(""); value << resource_definition->cpu_clock;
287 properties["cpu_clock"]=value.str();
288 value.str(""); value << resource_definition->nb_node;
289 properties["nb_node"]=value.str();
290 value.str(""); value << resource_definition->nb_proc_per_node;
291 properties["nb_proc_per_node"]=value.str();
293 properties["component_list"]="";
294 for(CORBA::ULong i=0; i < resource_definition->componentList.length(); i++)
297 properties["component_list"]=properties["component_list"]+",";
298 properties["component_list"]=properties["component_list"]+resource_definition->componentList[i].in();
305 * \param [in] compoNames
306 * \param [in,out] shutdownLevel
308 void SalomeContainerTools::Start(const std::vector<std::string>& compoNames, SalomeContainerHelper *schelp, SalomeContainerTools& sct, int& shutdownLevel, const Container *cont, const Task *askingNode)
310 CORBA::ORB_ptr orb(getSALOMERuntime()->getOrb());
311 SALOME_NamingService ns;
316 catch(SALOME_Exception& e)
318 throw Exception("SalomeContainer::start : Unable to contact the SALOME Naming Service");
320 CORBA::Object_var obj(ns.Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS));
321 Engines::ContainerManager_var contManager(Engines::ContainerManager::_narrow(obj));
324 std::string str(sct.getNotNullContainerName(cont,isEmptyName));
325 DEBTRACE("SalomeContainer::start " << str <<";"<< _sct.getHostName() <<";"<<_type);
327 // Finalize parameters with components found in the container
329 for(std::vector<std::string>::const_iterator iter=compoNames.begin();iter!=compoNames.end();iter++)
330 sct.addToComponentList(*iter);
332 Engines::ContainerParameters myparams(sct.getParameters());
334 std::string dftLauchMode(schelp->getDftLaunchMode());
335 myparams.mode=CORBA::string_dup(dftLauchMode.c_str());
338 //If a container_name is given try to find an already existing container in naming service
339 //If not found start a new container with the given parameters
340 if (dynamic_cast<SalomeContainerMonoHelper *>(schelp) && !isEmptyName)
342 myparams.mode=CORBA::string_dup("getorstart");
349 sct.setContainerName(str);
350 SetContainerNameOf(myparams,str);
351 Engines::Container_var trueCont(Engines::Container::_nil());
352 if(!isEmptyName && shutdownLevel==999)
354 //Make this only the first time start is called (_shutdownLevel==999)
355 //If the container is named, first try to get an existing container
356 //If there is an existing container use it and set the shutdown level to 3
357 //If there is no existing container, try to launch a new one and set the shutdown level to 2
361 trueCont=contManager->GiveContainer(myparams);
363 catch( const SALOME::SALOME_Exception& ex )
365 std::string msg="SalomeContainer::start : no existing container : ";
367 msg += ex.details.text.in();
374 if(!CORBA::is_nil(trueCont))
377 DEBTRACE( "container found: " << str << " " << _shutdownLevel );
382 myparams.mode="start";
383 DEBTRACE( "container not found: " << str << " " << _shutdownLevel);
387 if(CORBA::is_nil(trueCont))
390 // --- GiveContainer is used in batch mode to retreive launched containers,
391 // and is equivalent to StartContainer when not in batch.
392 trueCont=contManager->GiveContainer(myparams);
394 catch( const SALOME::SALOME_Exception& ex )
396 std::string msg="SalomeContainer::start : Unable to launch container in Salome : ";
398 msg += ex.details.text.in();
399 throw Exception(msg);
401 catch(CORBA::COMM_FAILURE&)
403 throw Exception("SalomeContainer::start : Unable to launch container in Salome : CORBA Comm failure detected");
405 catch(CORBA::Exception&)
407 throw Exception("SalomeContainer::start : Unable to launch container in Salome : Unexpected CORBA failure detected");
410 if(CORBA::is_nil(trueCont))
411 throw Exception("SalomeContainer::start : Unable to launch container in Salome. Check your CatalogResources.xml file");
413 schelp->setContainer(askingNode,trueCont);
415 CORBA::String_var containerName(trueCont->name()),hostName(trueCont->getHostName());
416 std::cerr << "SalomeContainer launched : " << containerName << " " << hostName << " " << trueCont->getPID() << std::endl;
419 CORBA::Object_ptr SalomeContainerTools::LoadComponent(SalomeContainerHelper *launchModeType, Container *cont, Task *askingNode)
421 DEBTRACE("SalomeContainer::loadComponent ");
422 cont->lock();//To be sure
423 const ComponentInstance *inst(askingNode?askingNode->getComponent():0);
424 if(!cont->isAlreadyStarted(askingNode))
428 cont->start(askingNode);
437 cont->lock();//To be sure
438 CORBA::Object_ptr objComponent=CORBA::Object::_nil();
439 std::string compoName(inst->getCompoName());
440 const char* componentName=compoName.c_str();
441 Engines::Container_var container(launchModeType->getContainer(askingNode));
445 bool isLoadable = container->load_component_Library(componentName, reason);
448 CORBA::string_free(reason);
450 Proc* p(cont->getProc());
453 std::string value(p->getProperty("DefaultStudyID"));
455 studyid= atoi(value.c_str());
457 // prepare component instance properties
458 Engines::FieldsDict_var env = new Engines::FieldsDict;
459 std::map<std::string, std::string> properties = inst->getProperties();
462 std::map<std::string,std::string> procMap=p->getProperties();
463 properties.insert(procMap.begin(),procMap.end());
466 std::map<std::string, std::string>::const_iterator itm;
467 env->length(properties.size());
469 for(itm = properties.begin(); itm != properties.end(); ++itm, item++)
471 DEBTRACE("envname="<<itm->first<<" envvalue="<< itm->second);
472 env[item].key= CORBA::string_dup(itm->first.c_str());
473 env[item].value <<= itm->second.c_str();
476 objComponent=container->create_component_instance_env(componentName, studyid, env, reason);
479 if(CORBA::is_nil(objComponent))
482 std::string text="Error while trying to create a new component: component '"+ compoName;
483 text=text+"' is not installed or it's a wrong name";
486 CORBA::string_free(reason);
487 throw Exception(text);
493 std::string SalomeContainerTools::GetPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
495 if(cont->isAlreadyStarted(askingNode))
497 Engines::Container_var container(launchModeType->getContainer(askingNode));
498 const char *what="/";
499 CORBA::String_var corbaStr(container->name());
500 std::string ret(corbaStr);
503 std::string::size_type i=ret.find_first_of(what,0);
504 i=ret.find_first_of(what, i==std::string::npos ? i:i+1);
505 if(i!=std::string::npos)
506 return ret.substr(i+1);
510 return "Not placed yet !!!";
513 std::string SalomeContainerTools::GetFullPlacementId(const SalomeContainerHelper *launchModeType, const Container *cont, const Task *askingNode)
515 if(cont->isAlreadyStarted(askingNode))
517 Engines::Container_var container(launchModeType->getContainer(askingNode));
520 CORBA::String_var corbaStr(container->name());
521 std::string ret(corbaStr);
526 return "Unknown_placement";
530 return "Not_placed_yet";