00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <rtt/RTT.hpp>
00031 #include "DeploymentComponent.hpp"
00032 #include "ComponentLoader.hpp"
00033 #include <rtt/extras/Activities.hpp>
00034 #include <rtt/extras/SequentialActivity.hpp>
00035 #include <rtt/marsh/PropertyMarshaller.hpp>
00036 #include <rtt/marsh/PropertyDemarshaller.hpp>
00037 #include <rtt/scripting/Scripting.hpp>
00038 #include <rtt/ConnPolicy.hpp>
00039 #include <rtt/plugin/PluginLoader.hpp>
00040 #include <boost/algorithm/string.hpp>
00041
00042
00043 #include <cstdio>
00044 #include <cstdlib>
00045
00046 #include "ocl/Component.hpp"
00047 #include <rtt/marsh/PropertyLoader.hpp>
00048
00049 #undef _POSIX_C_SOURCE
00050 #include <sys/types.h>
00051 #include <iostream>
00052 #include <fstream>
00053 #include <set>
00054
00055 using namespace Orocos;
00056
00057 namespace OCL
00058 {
00059 using namespace std;
00060 using namespace RTT;
00061 using namespace RTT::marsh;
00062 using namespace RTT::detail;
00063
00067 static std::set<string> valid_names;
00068
00069 extern char const* default_comp_path_build;
00070
00071 #define ORO_str(s) ORO__str(s)
00072 #define ORO__str(s) #s
00073
00074 DeploymentComponent::DeploymentComponent(std::string name, std::string siteFile)
00075 : RTT::TaskContext(name, Stopped),
00076 autoUnload("AutoUnload",
00077 "Stop, cleanup and unload all components loaded by the DeploymentComponent when it is destroyed.",
00078 true),
00079 validConfig("Valid", false),
00080 sched_RT("ORO_SCHED_RT", ORO_SCHED_RT ),
00081 sched_OTHER("ORO_SCHED_OTHER", ORO_SCHED_OTHER ),
00082 lowest_Priority("LowestPriority", RTT::os::LowestPriority ),
00083 highest_Priority("HighestPriority", RTT::os::HighestPriority ),
00084 target("Target",
00085 ORO_str(OROCOS_TARGET) ),
00086 nextGroup(0)
00087 {
00088 this->addProperty( "RTT_COMPONENT_PATH", compPath ).doc("Locations to look for components. Use a colon or semi-colon separated list of paths. Defaults to the environment variable with the same name.");
00089 this->addProperty( autoUnload );
00090 this->addAttribute( target );
00091
00092 this->addAttribute( validConfig );
00093 this->addAttribute( sched_RT );
00094 this->addAttribute( sched_OTHER );
00095 this->addAttribute( lowest_Priority );
00096 this->addAttribute( highest_Priority );
00097
00098
00099 this->addOperation("loadLibrary", &DeploymentComponent::loadLibrary, this, ClientThread).doc("Load a new library (component, plugin or typekit) into memory.").arg("Name", "The absolute or relative name of the to be loaded library.");
00100 this->addOperation("import", &DeploymentComponent::import, this, ClientThread).doc("Import all components, plugins and typekits from a given package or directory in the search path.").arg("Package", "The name absolute or relative name of a directory or package.");
00101 this->addOperation("path", &DeploymentComponent::path, this, ClientThread).doc("Add additional directories to the component search path without importing them.").arg("Paths", "A colon or semi-colon separated list of paths to search for packages.");
00102
00103 this->addOperation("loadComponent", &DeploymentComponent::loadComponent, this, ClientThread).doc("Load a new component instance from a library.").arg("Name", "The name of the to be created component").arg("Type", "The component type, used to lookup the library.");
00104 this->addOperation("loadService", &DeploymentComponent::loadService, this, ClientThread).doc("Load a discovered service or plugin in an existing component.").arg("Name", "The name of the component which will receive the service").arg("Service", "The name of the service or plugin.");
00105 this->addOperation("unloadComponent", &DeploymentComponent::unloadComponent, this, ClientThread).doc("Unload a loaded component instance.").arg("Name", "The name of the to be created component");
00106 this->addOperation("displayComponentTypes", &DeploymentComponent::displayComponentTypes, this, ClientThread).doc("Print out a list of all component types this component can create.");
00107 this->addOperation("getComponentTypes", &DeploymentComponent::getComponentTypes, this, ClientThread).doc("return a vector of all component types this component can create.");
00108
00109 this->addOperation("loadConfiguration", &DeploymentComponent::loadConfiguration, this, ClientThread).doc("Load a new XML configuration from a file (identical to loadComponents).").arg("File", "The file which contains the new configuration.");
00110 this->addOperation("loadConfigurationString", &DeploymentComponent::loadConfigurationString, this, ClientThread).doc("Load a new XML configuration from a string.").arg("Text", "The string which contains the new configuration.");
00111 this->addOperation("clearConfiguration", &DeploymentComponent::clearConfiguration, this, ClientThread).doc("Clear all configuration settings.");
00112
00113 this->addOperation("loadComponents", &DeploymentComponent::loadComponents, this, ClientThread).doc("Load components listed in an XML configuration file.").arg("File", "The file which contains the new configuration.");
00114 this->addOperation("configureComponents", &DeploymentComponent::configureComponents, this, ClientThread).doc("Apply a loaded configuration to the components and configure() them if AutoConf is set.");
00115 this->addOperation("startComponents", &DeploymentComponent::startComponents, this, ClientThread).doc("Start the components configured for AutoStart.");
00116 this->addOperation("stopComponents", &DeploymentComponent::stopComponents, this, ClientThread).doc("Stop all the configured components (with or without AutoStart).");
00117 this->addOperation("cleanupComponents", &DeploymentComponent::cleanupComponents, this, ClientThread).doc("Cleanup all the configured components (with or without AutoConf).");
00118 this->addOperation("unloadComponents", &DeploymentComponent::unloadComponents, this, ClientThread).doc("Unload all the previously loaded components.");
00119
00120 this->addOperation("runScript", &DeploymentComponent::runScript, this, ClientThread).doc("Runs a script.").arg("File", "An Orocos program script.");
00121 this->addOperation("kickStart", &DeploymentComponent::kickStart, this, ClientThread).doc("Calls loadComponents, configureComponents and startComponents in a row.").arg("File", "The file which contains the XML configuration to use.");
00122 this->addOperation("kickOutAll", &DeploymentComponent::kickOutAll, this, ClientThread).doc("Calls stopComponents, cleanupComponents and unloadComponents in a row.");
00123
00124 this->addOperation("kickOutComponent", &DeploymentComponent::kickOutComponent, this, ClientThread).doc("Calls stopComponents, cleanupComponent and unloadComponent in a row.").arg("comp_name", "component name");
00125 this->addOperation("kickOut", &DeploymentComponent::kickOut, this, ClientThread).doc("Calls stopComponents, cleanupComponents and unloadComponents in a row.").arg("File", "The file which contains the name of the components to kickOut (for example, the same used in kickStart).");
00126
00127
00128 typedef bool(DeploymentComponent::*DCFun)(const std::string&, const std::string&);
00129 DCFun cp = &DeploymentComponent::connectPeers;
00130 this->addOperation("connectPeers", cp, this, ClientThread).doc("Connect two Components known to this Component.").arg("One", "The first component.").arg("Two", "The second component.");
00131 cp = &DeploymentComponent::connectPorts;
00132 this->addOperation("connectPorts", cp, this, ClientThread).doc("DEPRECATED. Connect the Data Ports of two Components known to this Component.").arg("One", "The first component.").arg("Two", "The second component.");
00133 cp = &DeploymentComponent::addPeer;
00134 typedef bool(DeploymentComponent::*DC4Fun)(const std::string&, const std::string&,
00135 const std::string&, const std::string&);
00136 DC4Fun cp4 = &DeploymentComponent::connectPorts;
00137 this->addOperation("connectTwoPorts", cp4, this, ClientThread).doc("DEPRECATED. Connect two ports of Components known to this Component.")
00138 .arg("One", "The first component.")
00139 .arg("PortOne", "The port name of the first component.")
00140 .arg("Two", "The second component.")
00141 .arg("PortTwo", "The port name of the second component.");
00142 this->addOperation("createStream", &DeploymentComponent::createStream, this, ClientThread).doc("DEPRECATED. Creates a stream to or from a port.")
00143 .arg("component", "The component which owns 'port'.")
00144 .arg("port", "The port to create a stream from or to.")
00145 .arg("policy", "The connection policy which serves to describe the stream to be created.");
00146
00147
00148 this->addOperation("connect", &DeploymentComponent::connect, this, ClientThread).doc("Creates a connection between two ports.")
00149 .arg("portOne", "The first port of the connection. Use a dot-separated-path.")
00150 .arg("portTwo", "The second port of the connection. Use a dot-separated-path.")
00151 .arg("policy", "The connection policy which serves to describe the stream to be created. Use 'ConnPolicy()' to use the default.");
00152 this->addOperation("stream", &DeploymentComponent::stream, this, ClientThread).doc("Creates a stream to or from a port.")
00153 .arg("port", "The port to create a stream from or to. Use a dot-separated-path.")
00154 .arg("policy", "The connection policy which serves to describe the stream to be created. Use 'ConnPolicy()' to use the default.");
00155
00156 this->addOperation("connectServices", (bool(DeploymentComponent::*)(const std::string&, const std::string&))&DeploymentComponent::connectServices, this, ClientThread).doc("Connect the matching provides/requires services of two Components known to this Component.").arg("One", "The first component.").arg("Two", "The second component.");
00157
00158 this->addOperation("addPeer", cp, this, ClientThread).doc("Add a peer to a Component.").arg("From", "The first component.").arg("To", "The other component.");
00159 typedef void(DeploymentComponent::*RPFun)(const std::string&);
00160 RPFun rp = &RTT::TaskContext::removePeer;
00161 this->addOperation("removePeer", rp, this, ClientThread).doc("Remove a peer from this Component.").arg("PeerName", "The name of the peer to remove.");
00162
00163 this->addOperation("setActivity", &DeploymentComponent::setActivity, this, ClientThread).doc("Attach an activity to a Component.").arg("CompName", "The name of the Component.").arg("Period", "The period of the activity (set to 0.0 for non periodic).").arg("Priority", "The priority of the activity.").arg("SchedType", "The scheduler type of the activity.");
00164 this->addOperation("setPeriodicActivity", &DeploymentComponent::setPeriodicActivity, this, ClientThread).doc("Attach a periodic activity to a Component.").arg("CompName", "The name of the Component.").arg("Period", "The period of the activity.").arg("Priority", "The priority of the activity.").arg("SchedType", "The scheduler type of the activity.");
00165 this->addOperation("setSequentialActivity", &DeploymentComponent::setSequentialActivity, this, ClientThread).doc("Attach a 'stand alone' sequential activity to a Component.").arg("CompName", "The name of the Component.");
00166 this->addOperation("setSlaveActivity", &DeploymentComponent::setSlaveActivity, this, ClientThread).doc("Attach a 'stand alone' slave activity to a Component.").arg("CompName", "The name of the Component.").arg("Period", "The period of the activity (set to zero for non periodic).");
00167 this->addOperation("setMasterSlaveActivity", &DeploymentComponent::setMasterSlaveActivity, this, ClientThread).doc("Attach a slave activity with a master to a Component. The slave becomes a peer of the master as well.").arg("Master", "The name of the Component which is master of the Slave.").arg("Slave", "The name of the Component which gets the SlaveActivity.");
00168
00169 valid_names.insert("AutoUnload");
00170 valid_names.insert("UseNamingService");
00171 valid_names.insert("Server");
00172 valid_names.insert("AutoConf");
00173 valid_names.insert("AutoStart");
00174 valid_names.insert("AutoConnect");
00175 valid_names.insert("AutoSave");
00176 valid_names.insert("PropertyFile");
00177 valid_names.insert("UpdateProperties");
00178 valid_names.insert("LoadProperties");
00179 valid_names.insert("ProgramScript");
00180 valid_names.insert("StateMachineScript");
00181 valid_names.insert("Ports");
00182 valid_names.insert("Peers");
00183 valid_names.insert("Activity");
00184 valid_names.insert("Master");
00185 valid_names.insert("Properties");
00186 valid_names.insert("Service");
00187 valid_names.insert("Plugin");
00188 valid_names.insert("Provides");
00189 valid_names.insert("RunScript");
00190
00191
00192 if (siteFile.empty())
00193 siteFile = this->getName() + "-site.cpf";
00194 std::ifstream hassite(siteFile.c_str());
00195 if ( !hassite ) {
00196
00197 this->configure();
00198
00199
00200 log(Info) << "No site file was found. Importing 'ocl' by default." <<endlog();
00201 import("ocl");
00202 return;
00203 }
00204
00205
00206 log(Info) << "Using site file '" << siteFile << "'." << endlog();
00207 this->kickStart( siteFile );
00208
00209 }
00210
00211 bool DeploymentComponent::configureHook()
00212 {
00213 Logger::In in("DeploymentComponent::configure");
00214 char* paths = getenv("RTT_COMPONENT_PATH");
00215 if (compPath.empty() )
00216 {
00217 if (paths) {
00218 compPath = string(paths);
00219 } else {
00220 log(Info) <<"No RTT_COMPONENT_PATH set. Using default." <<endlog();
00221 compPath = default_comp_path_build ;
00222 }
00223 }
00224 log(Info) <<"RTT_COMPONENT_PATH was set to " << compPath << endlog();
00225 log(Info) <<"Re-scanning for plugins and components..."<<endlog();
00226 PluginLoader::Instance()->setPluginPath(compPath);
00227 ComponentLoader::Instance()->setComponentPath(compPath);
00228 ComponentLoader::Instance()->import(compPath);
00229 return true;
00230 }
00231
00232 bool DeploymentComponent::componentLoaded(RTT::TaskContext* c) { return true; }
00233
00234 void DeploymentComponent::componentUnloaded(TaskContext* c) { }
00235
00236 DeploymentComponent::~DeploymentComponent()
00237 {
00238
00239 if ( autoUnload.get() ) {
00240 kickOutAll();
00241 }
00242 ComponentLoader::Release();
00243 }
00244
00245 bool DeploymentComponent::connectPeers(const std::string& one, const std::string& other)
00246 {
00247 RTT::Logger::In in("DeploymentComponent::connectPeers");
00248 RTT::TaskContext* t1 = one == this->getName() ? this : this->getPeer(one);
00249 RTT::TaskContext* t2 = other == this->getName() ? this : this->getPeer(other);
00250 if (!t1) {
00251 log(Error)<< "No such peer: "<<one<<endlog();
00252 return false;
00253 }
00254 if (!t2) {
00255 log(Error) << "No such peer: "<<other<<endlog();
00256 return false;
00257 }
00258 return t1->connectPeers(t2);
00259 }
00260
00261 bool DeploymentComponent::addPeer(const std::string& from, const std::string& to)
00262 {
00263 RTT::Logger::In in("DeploymentComponent::addPeer");
00264 RTT::TaskContext* t1 = from == this->getName() ? this : this->getPeer(from);
00265 RTT::TaskContext* t2 = to == this->getName() ? this : this->getPeer(to);
00266 if (!t1) {
00267 log(Error)<< "No such peer: "<<from<<endlog();
00268 return false;
00269 }
00270 if (!t2) {
00271 log(Error)<< "No such peer: "<<to<<endlog();
00272 return false;
00273 }
00274 return t1->addPeer(t2);
00275 }
00276
00277 Service::shared_ptr DeploymentComponent::stringToService(string const& names) {
00278 std::vector<std::string> strs;
00279 boost::split(strs, names, boost::is_any_of("."));
00280
00281 string component = strs.front();
00282 if (!hasPeer(component) && component != this->getName() ) {
00283 log(Error) << "No such component: '"<< component <<"'" <<endlog();
00284 if ( names.find('.') != string::npos )
00285 log(Error)<< " when looking for service '" << names <<"'" <<endlog();
00286 return Service::shared_ptr();
00287 }
00288
00289 Service::shared_ptr ret = (component != this->getName() ? getPeer(component)->provides() : this->provides());
00290
00291
00292 strs.erase( strs.begin() );
00293
00294
00295 while ( !strs.empty() && ret) {
00296 ret = ret->getService( strs.front() );
00297 if (ret)
00298 strs.erase( strs.begin() );
00299 }
00300 if (!ret) {
00301 log(Error) <<"No such service: '"<< strs.front() <<"' while looking for service '"<< names<<"'"<<endlog();
00302 }
00303 return ret;
00304 }
00305
00306 base::PortInterface* DeploymentComponent::stringToPort(string const& names) {
00307 std::vector<std::string> strs;
00308 boost::split(strs, names, boost::is_any_of("."));
00309
00310 string component = strs.front();
00311 if (!hasPeer(component) && component != this->getName() ) {
00312 log(Error) << "No such component: '"<< component <<"'" ;
00313 log(Error)<< " when looking for port '" << names <<"'" <<endlog();
00314 return 0;
00315 }
00316
00317 Service::shared_ptr serv = (component != this->getName() ? getPeer(component)->provides() : this->provides());
00318 base::PortInterface* ret = 0;
00319
00320
00321 strs.erase( strs.begin() );
00322
00323
00324 while ( strs.size() != 1 && serv) {
00325 serv = serv->getService( strs.front() );
00326 if (serv)
00327 strs.erase( strs.begin() );
00328 }
00329 if (!serv) {
00330 log(Error) <<"No such service: '"<< strs.front() <<"' while looking for port '"<< names<<"'"<<endlog();
00331 return 0;
00332 }
00333 ret = serv->getPort(strs.front());
00334 if (!ret) {
00335 log(Error) <<"No such port: '"<< strs.front() <<"' while looking for port '"<< names<<"'"<<endlog();
00336 }
00337
00338 return ret;
00339 }
00340
00341 bool DeploymentComponent::connectPorts(const std::string& one, const std::string& other)
00342 {
00343 RTT::Logger::In in("DeploymentComponent::connectPorts");
00344 RTT::TaskContext* a, *b;
00345 a = getPeer(one);
00346 b = getPeer(other);
00347 if ( !a ) {
00348 log(Error) << one <<" could not be found."<< endlog();
00349 return false;
00350 }
00351 if ( !b ) {
00352 log(Error) << other <<" could not be found."<< endlog();
00353 return false;
00354 }
00355
00356 return a->connectPorts(b);
00357 }
00358
00359 bool DeploymentComponent::connectPorts(const std::string& one, const std::string& one_port,
00360 const std::string& other, const std::string& other_port)
00361 {
00362 RTT::Logger::In in("DeploymentComponent::connectPorts");
00363 Service::shared_ptr a,b;
00364 a = stringToService(one);
00365 b = stringToService(other);
00366 if (!a || !b)
00367 return false;
00368 base::PortInterface* ap, *bp;
00369 ap = a->getPort(one_port);
00370 bp = b->getPort(other_port);
00371 if ( !ap ) {
00372 log(Error) << one <<" does not have a port "<<one_port<< endlog();
00373 return false;
00374 }
00375 if ( !bp ) {
00376 log(Error) << other <<" does not have a port "<<other_port<< endlog();
00377 return false;
00378 }
00379
00380
00381 if ( ap->connected() && bp->connected() ) {
00382 log(Warning) << "Port '"<< ap->getName() << "' of Component '"<<a->getName()
00383 << "' and port '"<< bp->getName() << "' of Component '"<<b->getName()
00384 << "' are already connected but (probably) not to each other."<<endlog();
00385 }
00386
00387
00388 if ( ap->connectTo( bp ) ) {
00389
00390 log(Info)<< "Connected Port " << one +"." + one_port << " to "<< other +"." + other_port <<"." << endlog();
00391 return true;
00392 } else {
00393 log(Error)<< "Failed to connect Port " << one +"." + one_port << " to "<< other +"." + other_port <<"." << endlog();
00394 return true;
00395 }
00396 }
00397
00398 bool DeploymentComponent::createStream(const std::string& comp, const std::string& port, ConnPolicy policy)
00399 {
00400 Service::shared_ptr serv = stringToService(comp);
00401 if ( !serv )
00402 return false;
00403 PortInterface* porti = serv->getPort(port);
00404 if ( !porti ) {
00405 log(Error) <<"Service in component "<<comp<<" has no port "<< port << "."<< endlog();
00406 return false;
00407 }
00408 return porti->createStream( policy );
00409 }
00410
00411
00412 bool DeploymentComponent::connect(const std::string& one, const std::string& other, ConnPolicy cp)
00413 {
00414 RTT::Logger::In in("DeploymentComponent::connectPorts");
00415 base::PortInterface* ap, *bp;
00416 ap = stringToPort(one);
00417 bp = stringToPort(other);
00418 if (!ap || !bp)
00419 return false;
00420
00421
00422 if ( ap->connected() && bp->connected() ) {
00423 log(Warning) << "Port '"<< ap->getName() << "' of '"<< one
00424 << "' and port '"<< bp->getName() << "' of '"<< other
00425 << "' are already connected but (probably) not to each other."<<endlog();
00426 }
00427
00428
00429 if ( ap->connectTo( bp, cp ) ) {
00430
00431 log(Info)<< "Connected Port " << one << " to "<< other <<"." << endlog();
00432 return true;
00433 } else {
00434 log(Error)<< "Failed to connect Port " << one << " to "<< other <<"." << endlog();
00435 return false;
00436 }
00437 }
00438
00439 bool DeploymentComponent::stream(const std::string& port, ConnPolicy policy)
00440 {
00441 base::PortInterface* porti = stringToPort(port);
00442 if ( !porti ) {
00443 return false;
00444 }
00445 return porti->createStream( policy );
00446 }
00447
00448 bool DeploymentComponent::connectServices(const std::string& one, const std::string& other)
00449 {
00450 RTT::Logger::In in("DeploymentComponent::connectServices");
00451 RTT::TaskContext* a, *b;
00452 a = getPeer(one);
00453 b = getPeer(other);
00454 if ( !a ) {
00455 log(Error) << one <<" could not be found."<< endlog();
00456 return false;
00457 }
00458 if ( !b ) {
00459 log(Error) << other <<" could not be found."<< endlog();
00460 return false;
00461 }
00462
00463 return a->connectServices(b);
00464 }
00465
00466
00467 int string_to_oro_sched(const std::string& sched) {
00468 if ( sched == "ORO_SCHED_OTHER" )
00469 return ORO_SCHED_OTHER;
00470 if (sched == "ORO_SCHED_RT" )
00471 return ORO_SCHED_RT;
00472 log(Error)<<"Unknown scheduler type: "<< sched <<endlog();
00473 return -1;
00474 }
00475
00476 bool DeploymentComponent::loadConfigurationString(const std::string& text)
00477 {
00478 const char* tmpfile = ".loadConfigurationString.cpf";
00479 std::ofstream file( tmpfile );
00480 file << text.c_str();
00481 file.close();
00482 return this->loadConfiguration( tmpfile );
00483 }
00484
00485 bool DeploymentComponent::runScript(const std::string& file_name)
00486 {
00487 return this->getProvider<Scripting>("scripting")->runScript( file_name );
00488 }
00489
00490 bool DeploymentComponent::kickStart(const std::string& configurationfile)
00491 {
00492 int thisGroup = nextGroup;
00493 ++nextGroup;
00494 if ( this->loadComponentsInGroup(configurationfile, thisGroup) ) {
00495 if (this->configureComponentsGroup(thisGroup) ) {
00496 if ( this->startComponentsGroup(thisGroup) ) {
00497 log(Info) <<"Successfully loaded, configured and started components from "<< configurationfile <<endlog();
00498 return true;
00499 } else {
00500 log(Error) <<"Failed to start a component: aborting kick-start."<<endlog();
00501 }
00502 } else {
00503 log(Error) <<"Failed to configure a component: aborting kick-start."<<endlog();
00504 }
00505 } else {
00506 log(Error) <<"Failed to load a component: aborting kick-start."<<endlog();
00507 }
00508 return false;
00509 }
00510
00511 bool DeploymentComponent::kickOutAll()
00512 {
00513 bool ok = true;
00514 while (nextGroup != -1 )
00515 {
00516 ok &= kickOutGroup(nextGroup);
00517 --nextGroup;
00518 }
00519
00520 nextGroup = 0;
00521 return ok;
00522 }
00523
00524 bool DeploymentComponent::kickOutGroup(const int group)
00525 {
00526 bool sret = this->stopComponentsGroup(group);
00527 bool cret = this->cleanupComponentsGroup(group);
00528 bool uret = this->unloadComponentsGroup(group);
00529 if ( sret && cret && uret) {
00530 log(Info) << "Kick-out of group " << group << " successful."<<endlog();
00531 return true;
00532 }
00533
00534 log(Critical) << "Kick-out of group " << group << " failed: ";
00535 if (!sret)
00536 log(Critical) << " stopComponents() failed.";
00537 if (!cret)
00538 log(Critical) << " cleanupComponents() failed.";
00539 if (!uret)
00540 log(Critical) << " unloadComponents() failed.";
00541 log(Critical) << endlog();
00542 return false;
00543 }
00544
00545 bool DeploymentComponent::loadConfiguration(const std::string& configurationfile)
00546 {
00547 return this->loadComponents(configurationfile);
00548 }
00549
00550 bool DeploymentComponent::loadComponents(const std::string& configurationfile)
00551 {
00552 bool valid = loadComponentsInGroup(configurationfile, nextGroup);
00553 ++nextGroup;
00554 return valid;
00555 }
00556
00557 bool DeploymentComponent::loadComponentsInGroup(const std::string& configurationfile,
00558 const int group)
00559 {
00560 RTT::Logger::In in("DeploymentComponent::loadComponents");
00561
00562 RTT::PropertyBag from_file;
00563 log(Info) << "Loading '" <<configurationfile<<"' in group " << group << "."<< endlog();
00564
00565 bool failure = false;
00566
00567 bool valid = validConfig.get();
00568 marsh::PropertyDemarshaller demarshaller(configurationfile);
00569 try {
00570 if ( demarshaller.deserialize( from_file ) )
00571 {
00572 valid = true;
00573 log(Info)<<"Validating new configuration..."<<endlog();
00574 if ( from_file.empty() ) {
00575 log(Error)<< "Configuration was empty !" <<endlog();
00576 valid = false;
00577 }
00578
00579
00580 for (RTT::PropertyBag::iterator it= from_file.begin(); it!=from_file.end();it++) {
00581
00582 if ( (*it)->getName() == "Import" ) {
00583 RTT::Property<std::string> importp = *it;
00584 if ( !importp.ready() ) {
00585 log(Error)<< "Found 'Import' statement, but it is not of type='string'."<<endlog();
00586 valid = false;
00587 continue;
00588 }
00589 if ( this->import( importp.get() ) == false )
00590 valid = false;
00591 continue;
00592 }
00593 if ( (*it)->getName() == "LoadLibrary" ) {
00594 RTT::Property<std::string> importp = *it;
00595 if ( !importp.ready() ) {
00596 log(Error)<< "Found 'LoadLibrary' statement, but it is not of type='string'."<<endlog();
00597 valid = false;
00598 continue;
00599 }
00600 if ( this->loadLibrary( importp.get() ) == false )
00601 valid = false;
00602 continue;
00603 }
00604 if ( (*it)->getName() == "Path" ) {
00605 RTT::Property<std::string> pathp = *it;
00606 if ( !pathp.ready() ) {
00607 log(Error)<< "Found 'Path' statement, but it is not of type='string'."<<endlog();
00608 valid = false;
00609 continue;
00610 }
00611 this->path( pathp.get() );
00612 continue;
00613 }
00614 if ( (*it)->getName() == "Include" ) {
00615 RTT::Property<std::string> includep = *it;
00616 if ( !includep.ready() ) {
00617 log(Error)<< "Found 'Include' statement, but it is not of type='string'."<<endlog();
00618 valid = false;
00619 continue;
00620 }
00621
00622 if ( this->loadComponentsInGroup( includep.get(), group ) == false )
00623 valid = false;
00624 continue;
00625 }
00626
00627 RTT::Property<RTT::PropertyBag> comp = *it;
00628 if ( !comp.ready() ) {
00629 log(Error)<< "RTT::Property '"<< *it <<"' should be a struct, Include, Path or Import statement." << endlog();
00630 valid = false;
00631 continue;
00632 }
00633
00634
00635
00636 Property<ConnPolicy> cp_prop((*it)->getName(),"");
00637 assert( cp_prop.ready() );
00638 if ( cp_prop.compose( comp ) ) {
00639
00640 conmap[cp_prop.getName()].policy = cp_prop.get();
00641 log(Debug) << "Saw connection policy " << (*it)->getName() << endlog();
00642 continue;
00643 }
00644
00645
00646 for (RTT::PropertyBag::const_iterator optit= comp.rvalue().begin(); optit != comp.rvalue().end();optit++) {
00647 if ( valid_names.find( (*optit)->getName() ) == valid_names.end() ) {
00648 log(Error) << "Unknown type syntax: '"<< (*optit)->getName() << "' in component struct "<< comp.getName() <<endlog();
00649 valid = false;
00650 continue;
00651 }
00652 if ( (*optit)->getName() == "AutoConnect" ) {
00653 RTT::Property<bool> ps = comp.rvalue().getProperty("AutoConnect");
00654 if (!ps.ready()) {
00655 log(Error) << "AutoConnect must be of type <boolean>" << endlog();
00656 valid = false;
00657 } else
00658 comps[comp.getName()].autoconnect = ps.get();
00659 continue;
00660 }
00661 if ( (*optit)->getName() == "AutoStart" ) {
00662 RTT::Property<bool> ps = comp.rvalue().getProperty("AutoStart");
00663 if (!ps.ready()) {
00664 log(Error) << "AutoStart must be of type <boolean>" << endlog();
00665 valid = false;
00666 } else
00667 comps[comp.getName()].autostart = ps.get();
00668 continue;
00669 }
00670 if ( (*optit)->getName() == "AutoSave" ) {
00671 RTT::Property<bool> ps = comp.rvalue().getProperty("AutoSave");
00672 if (!ps.ready()) {
00673 log(Error) << "AutoSave must be of type <boolean>" << endlog();
00674 valid = false;
00675 } else
00676 comps[comp.getName()].autosave = ps.get();
00677 continue;
00678 }
00679 if ( (*optit)->getName() == "AutoConf" ) {
00680 RTT::Property<bool> ps = comp.rvalue().getProperty("AutoConf");
00681 if (!ps.ready()) {
00682 log(Error) << "AutoConf must be of type <boolean>" << endlog();
00683 valid = false;
00684 } else
00685 comps[comp.getName()].autoconf = ps.get();
00686 continue;
00687 }
00688 if ( (*optit)->getName() == "Server" ) {
00689 RTT::Property<bool> ps = comp.rvalue().getProperty("Server");
00690 if (!ps.ready()) {
00691 log(Error) << "Server must be of type <boolean>" << endlog();
00692 valid = false;
00693 } else
00694 comps[comp.getName()].server = ps.get();
00695 continue;
00696 }
00697 if ( (*optit)->getName() == "Service" || (*optit)->getName() == "Plugin" || (*optit)->getName() == "Provides") {
00698 RTT::Property<string> ps = *optit;
00699 if (!ps.ready()) {
00700 log(Error) << (*optit)->getName() << " must be of type <string>" << endlog();
00701 valid = false;
00702 } else {
00703 comps[comp.getName()].plugins.push_back(ps.value());
00704 }
00705 continue;
00706 }
00707 if ( (*optit)->getName() == "UseNamingService" ) {
00708 RTT::Property<bool> ps = comp.rvalue().getProperty("UseNamingService");
00709 if (!ps.ready()) {
00710 log(Error) << "UseNamingService must be of type <boolean>" << endlog();
00711 valid = false;
00712 } else
00713 comps[comp.getName()].use_naming = ps.get();
00714 continue;
00715 }
00716 if ( (*optit)->getName() == "PropertyFile" ) {
00717 RTT::Property<string> ps = comp.rvalue().getProperty("PropertyFile");
00718 if (!ps.ready()) {
00719 log(Error) << "PropertyFile must be of type <string>" << endlog();
00720 valid = false;
00721 } else
00722 comps[comp.getName()].configfile = ps.get();
00723 continue;
00724 }
00725 if ( (*optit)->getName() == "UpdateProperties" ) {
00726 RTT::Property<string> ps = comp.rvalue().getProperty("UpdateProperties");
00727 if (!ps.ready()) {
00728 log(Error) << "UpdateProperties must be of type <string>" << endlog();
00729 valid = false;
00730 } else
00731 comps[comp.getName()].configfile = ps.get();
00732 continue;
00733 }
00734 if ( (*optit)->getName() == "LoadProperties" ) {
00735 RTT::Property<string> ps = comp.rvalue().getProperty("LoadProperties");
00736 if (!ps.ready()) {
00737 log(Error) << "LoadProperties must be of type <string>" << endlog();
00738 valid = false;
00739 } else
00740 comps[comp.getName()].configfile = ps.get();
00741 continue;
00742 }
00743 if ( (*optit)->getName() == "Properties" ) {
00744 base::PropertyBase* ps = comp.rvalue().getProperty("Properties");
00745 if (!ps) {
00746 log(Error) << "Properties must be a <struct>" << endlog();
00747 valid = false;
00748 }
00749 continue;
00750 }
00751 if ( (*optit)->getName() == "RunScript" ) {
00752 base::PropertyBase* ps = comp.rvalue().getProperty("RunScript");
00753 if (!ps) {
00754 log(Error) << "RunScript must be of type <string>" << endlog();
00755 valid = false;
00756 }
00757 continue;
00758 }
00759 if ( (*optit)->getName() == "ProgramScript" ) {
00760 log(Warning) << "ProgramScript tag is deprecated. Rename it to 'RunScript'." <<endlog();
00761 base::PropertyBase* ps = comp.rvalue().getProperty("ProgramScript");
00762 if (!ps) {
00763 log(Error) << "ProgramScript must be of type <string>" << endlog();
00764 valid = false;
00765 }
00766 continue;
00767 }
00768 if ( (*optit)->getName() == "StateMachineScript" ) {
00769 log(Warning) << "StateMachineScript tag is deprecated. Rename it to 'RunScript'." <<endlog();
00770 base::PropertyBase* ps = comp.rvalue().getProperty("StateMachineScript");
00771 if (!ps) {
00772 log(Error) << "StateMachineScript must be of type <string>" << endlog();
00773 valid = false;
00774 }
00775 continue;
00776 }
00777 }
00778
00779
00780 RTT::TaskContext* c = 0;
00781 if ( (*it)->getName() == this->getName() )
00782 c = this;
00783 else
00784 c = this->getPeer( (*it)->getName() );
00785 if ( !c ) {
00786
00787 if (this->loadComponent( (*it)->getName(), comp.rvalue().getType() ) == false) {
00788 log(Warning)<< "Could not configure '"<< (*it)->getName() <<"': No such peer."<< endlog();
00789 valid = false;
00790 continue;
00791 }
00792 c = comps[(*it)->getName()].instance;
00793 } else {
00794
00795 comps[(*it)->getName()].instance = c;
00796 }
00797
00798 assert(c);
00799
00800
00801 vector<string>& services = comps[(*it)->getName()].plugins;
00802 for (vector<string>::iterator svit = services.begin(); svit != services.end(); ++svit) {
00803 if ( c->provides()->hasService( *svit ) == false) {
00804 PluginLoader::Instance()->loadService(*svit, c);
00805 }
00806 }
00807
00808
00809 if ( comp.value().getProperty("PropFile") )
00810 comp.value().getProperty("PropFile")->setName("PropertyFile");
00811
00812
00813 RTT::Property<RTT::PropertyBag>* ports = comp.value().getPropertyType<PropertyBag>("Ports");
00814 if ( ports != 0 ) {
00815 for (RTT::PropertyBag::iterator pit = ports->value().begin(); pit != ports->value().end(); pit++) {
00816 Property<string> portcon = *pit;
00817 if ( !portcon.ready() ) {
00818 log(Error)<< "RTT::Property '"<< (*pit)->getName() <<"' is not of type 'string'." << endlog();
00819 valid = false;
00820 continue;
00821 }
00822 base::PortInterface* p = c->ports()->getPort( portcon.getName() );
00823 if ( !p ) {
00824 log(Error)<< "Component '"<< c->getName() <<"' does not have a Port '"<< portcon.getName()<<"'." << endlog();
00825 valid = false;
00826 }
00827
00828 if (valid){
00829 string conn_name = portcon.value();
00830 bool to_add = true;
00831
00832
00833 for(unsigned int a=0; a < conmap[conn_name].ports.size(); a++)
00834 {
00835 if( conmap[conn_name].ports.at(a) == p && conmap[conn_name].owners.at(a) == c)
00836 {
00837 to_add = false;
00838 continue;
00839 }
00840 }
00841
00842 if(to_add)
00843 {
00844 log(Debug)<<"storing Port: "<<c->getName()<<"."<< portcon.getName();
00845 log(Debug)<<" in " << conn_name <<endlog();
00846 conmap[conn_name].ports.push_back( p );
00847 conmap[conn_name].owners.push_back( c );
00848 }
00849 }
00850 }
00851 }
00852
00853
00854
00855 if ( comp.value().find("Peers") != 0) {
00856 RTT::Property<RTT::PropertyBag> nm = comp.value().find("Peers");
00857 if ( !nm.ready() ) {
00858 log(Error)<<"RTT::Property 'Peers' must be a 'struct', was type "<< comp.value().find("Peers")->getType() << endlog();
00859 valid = false;
00860 } else {
00861 for (RTT::PropertyBag::const_iterator it= nm.rvalue().begin(); it != nm.rvalue().end();it++) {
00862 RTT::Property<std::string> pr = *it;
00863 if ( !pr.ready() ) {
00864 log(Error)<<"RTT::Property 'Peer' does not have type 'string'."<<endlog();
00865 valid = false;
00866 continue;
00867 }
00868 }
00869 }
00870 }
00871
00872
00873 if ( comp.value().find("Activity") != 0) {
00874 RTT::Property<RTT::PropertyBag> nm = comp.value().find("Activity");
00875 if ( !nm.ready() ) {
00876 log(Error)<<"RTT::Property 'Activity' must be a 'struct'."<<endlog();
00877 valid = false;
00878 } else {
00879 if ( nm.rvalue().getType() == "PeriodicActivity" ) {
00880 RTT::Property<double> per = nm.rvalue().getProperty("Period");
00881 if ( !per.ready() ) {
00882 log(Error)<<"Please specify period <double> of PeriodicActivity."<<endlog();
00883 valid = false;
00884 }
00885 RTT::Property<int> prio = nm.rvalue().getProperty("Priority");
00886 if ( !prio.ready() ) {
00887 log(Error)<<"Please specify priority <short> of PeriodicActivity."<<endlog();
00888 valid = false;
00889 }
00890 RTT::Property<string> sched;
00891 if (nm.rvalue().getProperty("Scheduler") )
00892 sched = nm.rvalue().getProperty("Scheduler");
00893 int scheduler = ORO_SCHED_RT;
00894 if ( sched.ready() ) {
00895 scheduler = string_to_oro_sched( sched.get());
00896 if (scheduler == -1 )
00897 valid = false;
00898 }
00899 if (valid) {
00900 this->setNamedActivity(comp.getName(), nm.rvalue().getType(), per.get(), prio.get(), scheduler );
00901 }
00902 } else
00903 if ( nm.rvalue().getType() == "Activity" || nm.rvalue().getType() == "NonPeriodicActivity" ) {
00904 RTT::Property<double> per = nm.rvalue().getProperty("Period");
00905 if ( !per.ready() ) {
00906 per = Property<double>("p","",0.0);
00907 }
00908 RTT::Property<int> prio = nm.rvalue().getProperty("Priority");
00909 if ( !prio.ready() ) {
00910 log(Error)<<"Please specify priority <short> of Activity."<<endlog();
00911 valid = false;
00912 }
00913 RTT::Property<string> sched = nm.rvalue().getProperty("Scheduler");
00914 int scheduler = ORO_SCHED_RT;
00915 if ( sched.ready() ) {
00916 int scheduler = string_to_oro_sched( sched.get());
00917 if (scheduler == -1 )
00918 valid = false;
00919 }
00920 if (valid) {
00921 this->setNamedActivity(comp.getName(), nm.rvalue().getType(), per.get(), prio.get(), scheduler );
00922 }
00923 } else
00924 if ( nm.rvalue().getType() == "SlaveActivity" ) {
00925 double period = 0.0;
00926 string master;
00927 if ( nm.rvalue().getProperty("Master") ) {
00928 master = nm.rvalue().getPropertyType<string>("Master")->get();
00929 if (valid) {
00930 this->setNamedActivity(comp.getName(), nm.rvalue().getType(), period, 0, 0, master );
00931 }
00932 } else {
00933
00934 if ( nm.rvalue().getProperty("Period") )
00935 period = nm.rvalue().getPropertyType<double>("Period")->get();
00936 if (valid) {
00937 this->setNamedActivity(comp.getName(), nm.rvalue().getType(), period, 0, 0 );
00938 }
00939 }
00940 } else
00941 if ( nm.rvalue().getType() == "SequentialActivity" ) {
00942 this->setNamedActivity(comp.getName(), nm.rvalue().getType(), 0, 0, 0 );
00943 } else {
00944 log(Error) << "Unknown activity type: " << nm.rvalue().getType()<<endlog();
00945 valid = false;
00946 }
00947 }
00948 } else {
00949
00950
00951 }
00952
00953
00954
00955
00956 string delimiter("@!#?<!");
00957 bool ret = updateProperty( root, from_file, comp.getName(), delimiter );
00958 if (!ret) {
00959 log(Error) << "Failed to store deployment properties for component " << comp.getName() <<endlog();
00960 valid = false;
00961 }
00962 else
00963 {
00964 log(Info) << "Added component " << (*it)->getName() << " to group " << group << endlog();
00965 comps[(*it)->getName()].group = group;
00966 }
00967 }
00968
00969 deletePropertyBag( from_file );
00970 }
00971 else
00972 {
00973 log(Error)<< "Some error occured while parsing "<< configurationfile <<endlog();
00974 failure = true;
00975 }
00976 } catch (...)
00977 {
00978 log(Error)<< "Uncaught exception in loadcomponents() !"<< endlog();
00979 failure = true;
00980 }
00981 validConfig.set(valid);
00982 return !failure && valid;
00983 }
00984
00985 bool DeploymentComponent::configureComponents()
00986 {
00987 RTT::Logger::In in("DeploymentComponent::configureComponents");
00988
00989 bool valid = true;
00990 for (int group = nextGroup - 1; group > 0; --group) {
00991 valid &= configureComponentsGroup(group);
00992 }
00993 return valid;
00994 }
00995
00996 bool DeploymentComponent::configureComponentsGroup(const int group)
00997 {
00998 RTT::Logger::In in("DeploymentComponent::configureComponents");
00999 if ( root.empty() ) {
01000 RTT::Logger::log() << RTT::Logger::Error
01001 << "No components loaded by DeploymentComponent !" <<endlog();
01002 return false;
01003 }
01004
01005 bool valid = true;
01006 log(Info) << "Configuring components in group " << group << endlog();
01007
01008
01009 for (RTT::PropertyBag::iterator it= root.begin(); it!=root.end();it++) {
01010
01011 RTT::Property<RTT::PropertyBag> comp = *it;
01012
01013
01014 if (group != comps[ comp.getName() ].group) {
01015 continue;
01016 }
01017
01018 RTT::TaskContext* peer = comps[ comp.getName() ].instance;
01019 if ( !peer ) {
01020 log(Error) << "Peer not found: "<< comp.getName() <<endlog();
01021 valid=false;
01022 continue;
01023 }
01024
01025 comps[comp.getName()].instance = peer;
01026
01027
01028
01029 RTT::Property<RTT::PropertyBag> peers = comp.rvalue().find("Peers");
01030 if ( peers.ready() )
01031 for (RTT::PropertyBag::const_iterator it= peers.rvalue().begin(); it != peers.rvalue().end();it++) {
01032 RTT::Property<string> nm = (*it);
01033 if ( nm.ready() )
01034 {
01035 this->addPeer( comps[comp.getName()].instance->getName(), nm.value() );
01036 log(Info) << this->getName() << " connects " <<
01037 comps[comp.getName()].instance->getName() << " to "<< nm.value() << endlog();
01038 }
01039 else {
01040 log(Error) << "Wrong property type in Peers struct. Expected property of type 'string',"
01041 << " got type "<< (*it)->getType() <<endlog();
01042 valid = false;
01043 }
01044 }
01045 }
01046
01047
01048 for(ConMap::iterator it = conmap.begin(); it != conmap.end(); ++it) {
01049 ConnectionData *connection = &(it->second);
01050 std::string connection_name = it->first;
01051
01052 if ( connection->ports.size() == 1 ){
01053 string owner = connection->owners[0]->getName();
01054 string portname = connection->ports.front()->getName();
01055 string porttype = dynamic_cast<InputPortInterface*>(connection->ports.front() ) ? "InputPort" : "OutputPort";
01056 if ( connection->ports.front()->createStream( connection->policy ) == false) {
01057 log(Warning) << "Creating stream with name "<<connection_name<<" with Port "<<portname<<" from "<< owner << " failed."<< endlog();
01058 } else {
01059 log(Info) << "Component "<< owner << "'s " + porttype<< " " + portname << " will stream to "<< connection->policy.name_id << endlog();
01060 }
01061 continue;
01062 }
01063
01064 base::PortInterface* writer = 0;
01065 ConnectionData::Ports::iterator p = connection->ports.begin();
01066
01067
01068 vector<OutputPortInterface*> writers;
01069 while (p !=connection->ports.end() ) {
01070 if ( OutputPortInterface* out = dynamic_cast<base::OutputPortInterface*>( *p ) ) {
01071 if ( writer ) {
01072 log(Info) << "Forming multi-output connections with additional OutputPort " << (*p)->getName() << "."<<endlog();
01073 } else
01074 writer = *p;
01075 writers.push_back( out );
01076 std::string owner = it->second.owners[p - it->second.ports.begin()]->getName();
01077 log(Info) << "Component "<< owner << "'s OutputPort "<< writer->getName()<< " will write topic "<<it->first<< endlog();
01078 }
01079 ++p;
01080 }
01081
01082
01083 if ( writer == 0 ) {
01084 log(Error) << "No OutputPort listed that writes " << it->first << endlog();
01085 valid = false;
01086 break;
01087 }
01088
01089
01090 p = connection->ports.begin();
01091 vector<OutputPortInterface*>::iterator w = writers.begin();
01092
01093 while (w != writers.end() ) {
01094 while (p != connection->ports.end() ) {
01095
01096 if ( dynamic_cast<base::InputPortInterface*>( *p ) )
01097 {
01098 string owner = connection->owners[p - connection->ports.begin()]->getName();
01099
01100
01101 if ( (*w)->connectTo( *p, connection->policy ) == false) {
01102 log(Error) << "Could not subscribe InputPort "<< owner<<"."<< (*p)->getName() << " to topic " << (*w)->getName() <<'/'<< connection_name <<endlog();
01103 valid = false;
01104 } else {
01105 log(Info) << "Subscribed InputPort "<< owner<<"."<< (*p)->getName() <<" to topic " << (*w)->getName() <<'/'<< connection_name <<endlog();
01106 }
01107 }
01108 ++p;
01109 }
01110 ++w;
01111 p = connection->ports.begin();
01112 }
01113 }
01114
01115
01116 for (RTT::PropertyBag::iterator it= root.begin(); it!=root.end();it++) {
01117 RTT::Property<RTT::PropertyBag> comp = *it;
01118 if ( !comp.ready() )
01119 continue;
01120
01121
01122 if (group != comps[ comp.getName() ].group) {
01123 continue;
01124 }
01125
01126 RTT::TaskContext* peer = comps[ comp.getName() ].instance;
01127
01128
01129
01130
01131 if ( comps[comp.getName()].autoconnect ) {
01132
01133 RTT::TaskContext::PeerList peers = peer->getPeerList();
01134 for(RTT::TaskContext::PeerList::iterator pit = peers.begin(); pit != peers.end(); ++pit) {
01135 if ( comps.count( *pit ) && comps[ *pit ].autoconnect ) {
01136 RTT::TaskContext* other = peer->getPeer( *pit );
01137 ::RTT::connectPorts( peer, other );
01138 }
01139 }
01140 }
01141 }
01142
01143
01144 for (RTT::PropertyBag::iterator it= root.begin(); it!=root.end();it++) {
01145
01146 RTT::Property<RTT::PropertyBag> comp = *it;
01147
01148
01149 if (group != comps[ comp.getName() ].group) {
01150 continue;
01151 }
01152
01153 RTT::Property<string> dummy;
01154 RTT::TaskContext* peer = comps[ comp.getName() ].instance;
01155
01156
01157 if ( peer->getTaskState() > Stopped) {
01158 log(Warning) << "Component "<< peer->getName()<< " doesn't need to be configured (already Running)." <<endlog();
01159 continue;
01160 }
01161
01162
01163 for (RTT::PropertyBag::const_iterator pf = comp.rvalue().begin(); pf!= comp.rvalue().end(); ++pf) {
01164
01165 if ( (*pf)->getName() == "Properties"){
01166 RTT::Property<RTT::PropertyBag> props = *pf;
01167 bool ret = updateProperties( *peer->properties(), props);
01168 if (!ret) {
01169 log(Error) << "Failed to configure properties from main configuration file for component "<< comp.getName() <<endlog();
01170 valid = false;
01171 } else {
01172 log(Info) << "Configured Properties of "<< comp.getName() <<" from main configuration file." <<endlog();
01173 }
01174 }
01175 }
01176
01177 for (RTT::PropertyBag::const_iterator pf = comp.rvalue().begin(); pf!= comp.rvalue().end(); ++pf) {
01178
01179 if ( (*pf)->getName() == "PropertyFile" || (*pf)->getName() == "UpdateProperties" || (*pf)->getName() == "LoadProperties"){
01180 dummy = *pf;
01181 string filename = dummy.get();
01182 marsh::PropertyLoader pl;
01183 bool strict = (*pf)->getName() == "PropertyFile" ? true : false;
01184 bool load = (*pf)->getName() == "LoadProperties" ? true : false;
01185 bool ret;
01186 if (!load)
01187 ret = pl.configure( filename, peer, strict );
01188 else
01189 ret = pl.load(filename, peer);
01190 if (!ret) {
01191 log(Error) << "Failed to configure properties for component "<< comp.getName() <<endlog();
01192 valid = false;
01193 } else {
01194 log(Info) << "Configured Properties of "<< comp.getName() << " from "<<filename<<endlog();
01195 comps[ comp.getName() ].loadedProperties = true;
01196 }
01197 }
01198 }
01199
01200
01201 if ( comps[comp.getName()].act ) {
01202 if ( peer->getActivity() ) {
01203 log(Info) << "Re-setting activity of "<< comp.getName() <<endlog();
01204 } else {
01205 log(Info) << "Setting activity of "<< comp.getName() <<endlog();
01206 }
01207 peer->setActivity( comps[comp.getName()].act );
01208 assert( peer->engine()->getActivity() == comps[comp.getName()].act );
01209 comps[comp.getName()].act = 0;
01210 }
01211
01212
01213 for (RTT::PropertyBag::const_iterator ps = comp.rvalue().begin(); ps!= comp.rvalue().end(); ++ps) {
01214 RTT::Property<string> script;
01215 if ( (*ps)->getName() == "RunScript" )
01216 script = *ps;
01217 if ( script.ready() ) {
01218 valid = valid && peer->getProvider<Scripting>("scripting")->runScript( script.get() );
01219 }
01220
01221 RTT::Property<string> pscript;
01222 if ( (*ps)->getName() == "ProgramScript" )
01223 pscript = *ps;
01224 if ( pscript.ready() ) {
01225 valid = valid && peer->getProvider<Scripting>("scripting")->loadPrograms( pscript.get() );
01226 }
01227 RTT::Property<string> sscript;
01228 if ( (*ps)->getName() == "StateMachineScript" )
01229 sscript = *ps;
01230 if ( sscript.ready() ) {
01231 valid = valid && peer->getProvider<Scripting>("scripting")->loadStateMachines( sscript.get() );
01232 }
01233 }
01234
01235
01236 if (comps[comp.getName()].autoconf )
01237 {
01238 if( !peer->isRunning() )
01239 {
01240 OperationCaller<bool(void)> peerconfigure = peer->getOperation("configure");
01241 if ( peerconfigure() == false)
01242 valid = false;
01243 }
01244 else
01245 log(Warning) << "Apparently component "<< peer->getName()<< " don't need to be configured (already Running)." <<endlog();
01246 }
01247 }
01248
01249
01250
01251 if (!valid) {
01252 for ( CompList::iterator cit = comps.begin(); cit != comps.end(); ++cit) {
01253 ComponentData* cd = &(cit->second);
01254 if ( group == cd->group && cd->loaded && cd->autoconf &&
01255 (cd->instance->getTaskState() != TaskCore::Stopped) &&
01256 (cd->instance->getTaskState() != TaskCore::Running))
01257 log(Error) << "Failed to configure component "<< cd->instance->getName()
01258 << ": state is " << cd->instance->getTaskState() <<endlog();
01259 }
01260 } else {
01261 log(Info) << "Configuration successful for group " << group << "." <<endlog();
01262 }
01263
01264 validConfig.set(valid);
01265 return valid;
01266 }
01267
01268 bool DeploymentComponent::startComponents()
01269 {
01270
01271 bool valid = true;
01272 for (int group = nextGroup - 1; group > 0; --group) {
01273 valid &= startComponentsGroup(group);
01274 }
01275 return valid;
01276 }
01277
01278 bool DeploymentComponent::startComponentsGroup(const int group)
01279 {
01280 RTT::Logger::In in("DeploymentComponent::startComponentsGroup");
01281 if (validConfig.get() == false) {
01282 log(Error) << "Not starting components with invalid configuration." <<endlog();
01283 return false;
01284 }
01285 bool valid = true;
01286 for (RTT::PropertyBag::iterator it= root.begin(); it!=root.end();it++) {
01287
01288
01289 if (group != comps[ (*it)->getName() ].group) {
01290 continue;
01291 }
01292
01293 TaskContext* peer = comps[ (*it)->getName() ].instance;
01294
01295
01296
01297 if (peer->isRunning())
01298 {
01299 continue;
01300 }
01301
01302
01303 OperationCaller<bool(void)> peerstart = peer->getOperation("start");
01304 if (comps[(*it)->getName()].autostart )
01305 if ( !peer || ( !peer->isRunning() && peerstart() == false) )
01306 valid = false;
01307 }
01308
01309 if (!valid) {
01310 for ( CompList::iterator cit = comps.begin(); cit != comps.end(); ++cit) {
01311 ComponentData* it = &(cit->second);
01312
01313
01314 if (group != it->group) {
01315 continue;
01316 }
01317
01318 if ( it->instance == 0 ) {
01319 log(Error) << "Failed to start component "<< cit->first << ": not found." << endlog();
01320 continue;
01321 }
01322 if ( it->autostart && it->instance->getTaskState() != base::TaskCore::Running )
01323 log(Error) << "Failed to start component "<< it->instance->getName() <<endlog();
01324 }
01325 } else {
01326 log(Info) << "Startup of 'AutoStart' components successful for group " << group << "." <<endlog();
01327 }
01328 return valid;
01329 }
01330
01331 bool DeploymentComponent::stopComponents()
01332 {
01333
01334 bool valid = true;
01335 for (int group = nextGroup ; group != -1; --group) {
01336 valid &= stopComponentsGroup(group);
01337 }
01338 return valid;
01339 }
01340
01341 bool DeploymentComponent::stopComponentsGroup(const int group)
01342 {
01343 RTT::Logger::In in("DeploymentComponent::stopComponentsGroup");
01344 log(Info) << "Stopping group " << group << endlog();
01345 bool valid = true;
01346
01347 for ( CompList::iterator cit = comps.begin(); cit != comps.end(); ++cit) {
01348 ComponentData* it = &(cit->second);
01349 if ( (group == it->group) && it->instance && !it->proxy ) {
01350 OperationCaller<bool(void)> instancestop = it->instance->getOperation("stop");
01351 if ( !it->instance->isRunning() ||
01352 instancestop() ) {
01353 log(Info) << "Stopped "<< it->instance->getName() <<endlog();
01354 } else {
01355 log(Error) << "Could not stop loaded Component "<< it->instance->getName() <<endlog();
01356 valid = false;
01357 }
01358 }
01359 }
01360 return valid;
01361 }
01362
01363 bool DeploymentComponent::cleanupComponents()
01364 {
01365
01366 bool valid = true;
01367 for (int group = nextGroup ; group != -1; --group) {
01368 valid &= cleanupComponentsGroup(group);
01369 }
01370 return valid;
01371 }
01372
01373 bool DeploymentComponent::cleanupComponentsGroup(const int group)
01374 {
01375 RTT::Logger::In in("DeploymentComponent::cleanupComponentsGroup");
01376 bool valid = true;
01377 log(Info) << "Cleaning up group " << group << endlog();
01378
01379 for ( CompList::iterator cit = comps.begin(); cit != comps.end(); ++cit) {
01380 ComponentData* it = &(cit->second);
01381
01382
01383 if (group != it->group) {
01384 continue;
01385 }
01386
01387 if (it->instance && !it->proxy) {
01388 if ( it->instance->getTaskState() <= base::TaskCore::Stopped ) {
01389 if ( it->autosave && !it->configfile.empty()) {
01390 if (it->loadedProperties) {
01391 string file = it->configfile;
01392 PropertyLoader pl;
01393 bool ret = pl.save( file, it->instance, true );
01394 if (!ret) {
01395 log(Error) << "Failed to save properties for component "<< it->instance->getName() <<endlog();
01396 valid = false;
01397 } else {
01398 log(Info) << "Refusing to save property file that was not loaded for "<< it->instance->getName() <<endlog();
01399 }
01400 } else if (it->autosave) {
01401 log(Error) << "AutoSave set but no property file specified. Specify one using the UpdateProperties simple element."<<endlog();
01402 }
01403 } else if (it->autosave) {
01404 log(Error) << "AutoSave set but no property file specified. Specify one using the UpdateProperties simple element."<<endlog();
01405 }
01406 OperationCaller<bool(void)> instancecleanup = it->instance->getOperation("cleanup");
01407 instancecleanup();
01408 log(Info) << "Cleaned up "<< it->instance->getName() <<endlog();
01409 } else {
01410 log(Error) << "Could not cleanup Component "<< it->instance->getName() << " (not Stopped)"<<endlog();
01411 valid = false;
01412 }
01413 }
01414 }
01415 return valid;
01416 }
01417
01418 bool DeploymentComponent::unloadComponents()
01419 {
01420
01421 bool valid = true;
01422 for (int group = nextGroup ; group != -1; --group) {
01423 valid &= unloadComponentsGroup(group);
01424 }
01425 return valid;
01426 }
01427
01428 bool DeploymentComponent::unloadComponentsGroup(const int group)
01429 {
01430 log(Info) << "Unloading group " << group << endlog();
01431
01432 bool valid = true;
01433 CompList::iterator cit = comps.begin();
01434 while ( valid && cit != comps.end())
01435 {
01436 ComponentData* it = &(cit->second);
01437 if (group == it->group)
01438 {
01439
01440 valid &= this->unloadComponentImpl(cit);
01441
01442 cit = comps.begin();
01443 }
01444 else
01445 {
01446 ++cit;
01447 }
01448 }
01449
01450
01451 return valid;
01452 }
01453
01454 void DeploymentComponent::clearConfiguration()
01455 {
01456 log(Info) << "Clearing configuration options."<< endlog();
01457 conmap.clear();
01458 deletePropertyBag( root );
01459 }
01460
01461 bool DeploymentComponent::import(const std::string& package)
01462 {
01463 RTT::Logger::In in("DeploymentComponent::import");
01464 return ComponentLoader::Instance()->import( package, "" );
01465 }
01466
01467 void DeploymentComponent::path(const std::string& path)
01468 {
01469 RTT::Logger::In in("DeploymentComponent::path");
01470 ComponentLoader::Instance()->setComponentPath( ComponentLoader::Instance()->getComponentPath() + path );
01471 PluginLoader::Instance()->setPluginPath( PluginLoader::Instance()->getPluginPath() + path );
01472 }
01473
01474 bool DeploymentComponent::loadLibrary(const std::string& name)
01475 {
01476 RTT::Logger::In in("DeploymentComponent::loadLibrary");
01477 return PluginLoader::Instance()->loadLibrary(name) || ComponentLoader::Instance()->loadLibrary(name);
01478 }
01479
01480 bool DeploymentComponent::loadService(const std::string& name, const std::string& type) {
01481 TaskContext* peer = 0;
01482 if (name == getName() )
01483 peer = this;
01484 else if ( (peer = getPeer(name)) == 0) {
01485 log(Error)<<"No such peer: "<< name<< ". Can not load service '"<<type<<"'."<<endlog();
01486 return false;
01487 }
01488
01489
01490 if (peer->provides()->hasService(type))
01491 return true;
01492 return PluginLoader::Instance()->loadService(type, peer);
01493 }
01494
01495
01496 bool DeploymentComponent::loadComponent(const std::string& name, const std::string& type)
01497 {
01498 RTT::Logger::In in("DeploymentComponent::loadComponent");
01499
01500 if ( type == "RTT::PropertyBag" )
01501 return false;
01502
01503 if ( this->getPeer(name) || ( comps.find(name) != comps.end() && comps[name].instance != 0) ) {
01504 log(Error) <<"Failed to load component with name "<<name<<": already present as peer or loaded."<<endlog();
01505 return false;
01506 }
01507
01508 TaskContext* instance = ComponentLoader::Instance()->loadComponent(name, type);
01509
01510 if (!instance) {
01511 return false;
01512 }
01513
01514
01515 comps[name].instance = instance;
01516
01517 if (!this->componentLoaded( instance ) ) {
01518 log(Error) << "This deployer type refused to connect to "<< instance->getName() << ": aborting !" << endlog(Error);
01519 comps[name].instance = 0;
01520 ComponentLoader::Instance()->unloadComponent( instance );
01521 return false;
01522 }
01523
01524
01525 this->addPeer( instance );
01526 log(Info) << "Adding "<< instance->getName() << " as new peer: OK."<< endlog(Info);
01527
01528 comps[name].loaded = true;
01529
01530 return true;
01531 }
01532
01537 bool DeploymentComponent::unloadComponentImpl( CompList::iterator cit )
01538 {
01539 bool valid = true;
01540 ComponentData* it = &(cit->second);
01541 std::string name = cit->first;
01542
01543 if ( it->loaded && it->instance ) {
01544 if ( !it->instance->isRunning() ) {
01545 if (!it->proxy ) {
01546
01547 componentUnloaded( it->instance );
01548 log(Debug) << "Disconnecting " <<name <<endlog();
01549 it->instance->disconnect();
01550 log(Debug) << "Terminating " <<name <<endlog();
01551 } else
01552 log(Debug) << "Removing proxy for " <<name <<endlog();
01553
01554
01555 for( ConMap::iterator cmit = conmap.begin(); cmit != conmap.end(); ++cmit) {
01556 size_t n = 0;
01557 while ( n != cmit->second.owners.size() ) {
01558 if (cmit->second.owners[n] == it->instance ) {
01559 cmit->second.owners.erase( cmit->second.owners.begin() + n );
01560 cmit->second.ports.erase( cmit->second.ports.begin() + n );
01561 n = 0;
01562 } else
01563 ++n;
01564 }
01565 }
01566
01567 RTT::Property<RTT::PropertyBag>* pcomp = root.getPropertyType<PropertyBag>(name);
01568 if (pcomp) {
01569 root.removeProperty(pcomp);
01570 }
01571
01572
01573 delete it->act;
01574 it->act = 0;
01575 ComponentLoader::Instance()->unloadComponent( it->instance );
01576 it->instance = 0;
01577 log(Info) << "Disconnected and destroyed "<< name <<endlog();
01578 } else {
01579 log(Error) << "Could not unload Component "<< name <<": still running." <<endlog();
01580 valid=false;
01581 }
01582 }
01583 if (valid) {
01584
01585
01586 comps.erase(cit);
01587 }
01588 return valid;
01589 }
01590
01591 bool DeploymentComponent::unloadComponent(const std::string& name)
01592 {
01593 CompList::iterator it;
01594
01595 if ( comps.count( name ) == 0 || comps[name].loaded == false ) {
01596 log(Error) << "Can't unload component '"<<name<<"': not loaded by "<<this->getName()<<endlog();
01597 return false;
01598 }
01599
01600
01601 it = comps.find(name);
01602
01603 if ( this->unloadComponentImpl( it ) == false )
01604 return false;
01605
01606 log(Info) << "Successfully unloaded component "<<name<<"."<<endlog();
01607 return true;
01608 }
01609
01610 void DeploymentComponent::displayComponentTypes() const
01611 {
01612 OCL::FactoryMap::iterator it;
01613 cout << "I can create the following component types: " <<endl;
01614 for(it = OCL::ComponentFactories::Instance().begin(); it != OCL::ComponentFactories::Instance().end(); ++it) {
01615 cout << " " << it->first << endl;
01616 }
01617 if ( OCL::ComponentFactories::Instance().size() == 0 )
01618 cout << " (none)"<<endl;
01619 }
01620
01621 std::vector<std::string> DeploymentComponent::getComponentTypes() const
01622 {
01623 std::vector<std::string> s;
01624 OCL::FactoryMap::iterator it;
01625 for(it = OCL::ComponentFactories::Instance().begin(); it != OCL::ComponentFactories::Instance().end(); ++it)
01626 s.push_back(it->first);
01627
01628 return s;
01629 }
01630
01631 bool DeploymentComponent::setActivity(const std::string& comp_name,
01632 double period, int priority,
01633 int scheduler)
01634 {
01635 if ( this->setNamedActivity(comp_name, "Activity", period, priority, scheduler) ) {
01636 assert( comps[comp_name].instance );
01637 assert( comps[comp_name].act );
01638 comps[comp_name].instance->setActivity( comps[comp_name].act );
01639 comps[comp_name].act = 0;
01640 return true;
01641 }
01642 return false;
01643 }
01644
01645 bool DeploymentComponent::setPeriodicActivity(const std::string& comp_name,
01646 double period, int priority,
01647 int scheduler)
01648 {
01649 if ( this->setNamedActivity(comp_name, "PeriodicActivity", period, priority, scheduler) ) {
01650 assert( comps[comp_name].instance );
01651 assert( comps[comp_name].act );
01652 comps[comp_name].instance->setActivity( comps[comp_name].act );
01653 comps[comp_name].act = 0;
01654 return true;
01655 }
01656 return false;
01657 }
01658
01659 bool DeploymentComponent::setSlaveActivity(const std::string& comp_name,
01660 double period)
01661 {
01662 if ( this->setNamedActivity(comp_name, "SlaveActivity", period, 0, ORO_SCHED_OTHER ) ) {
01663 assert( comps[comp_name].instance );
01664 assert( comps[comp_name].act );
01665 comps[comp_name].instance->setActivity( comps[comp_name].act );
01666 comps[comp_name].act = 0;
01667 return true;
01668 }
01669 return false;
01670 }
01671
01672 bool DeploymentComponent::setSequentialActivity(const std::string& comp_name)
01673 {
01674 if ( this->setNamedActivity(comp_name, "SequentialActivity", 0, 0, 0 ) ) {
01675 assert( comps[comp_name].instance );
01676 assert( comps[comp_name].act );
01677 comps[comp_name].instance->setActivity( comps[comp_name].act );
01678 comps[comp_name].act = 0;
01679 return true;
01680 }
01681 return false;
01682 }
01683
01684 bool DeploymentComponent::setMasterSlaveActivity(const std::string& master,
01685 const std::string& slave)
01686 {
01687 if ( this->setNamedActivity(slave, "SlaveActivity", 0, 0, ORO_SCHED_OTHER, master ) ) {
01688 assert( comps[slave].instance );
01689 assert( comps[slave].act );
01690 comps[slave].instance->setActivity( comps[slave].act );
01691 comps[slave].act = 0;
01692 return true;
01693 }
01694 return false;
01695 }
01696
01697
01698 bool DeploymentComponent::setNamedActivity(const std::string& comp_name,
01699 const std::string& act_type,
01700 double period, int priority,
01701 int scheduler, const std::string& master_name)
01702 {
01703
01704
01705 RTT::TaskContext* peer = 0;
01706 base::ActivityInterface* master_act = 0;
01707 if ( comp_name == this->getName() )
01708 peer = this;
01709 else
01710 if ( comps.count(comp_name) )
01711 peer = comps[comp_name].instance;
01712 else
01713 peer = this->getPeer(comp_name);
01714 if (!peer) {
01715 log(Error) << "Can't create Activity: component "<<comp_name<<" not found."<<endlog();
01716 return false;
01717 }
01718 if ( !master_name.empty() ) {
01719 if ( master_name == this->getName() )
01720 master_act = this->engine()->getActivity();
01721 else
01722 if ( comps.count(master_name) && comps[master_name].act )
01723 master_act = comps[master_name].act;
01724 else
01725 master_act = this->getPeer(master_name) ? getPeer(master_name)->engine()->getActivity() : 0;
01726
01727 if ( !this->getPeer(master_name) ) {
01728 log(Error) << "Can't create SlaveActivity: Master component "<<master_name<<" not known as peer."<<endlog();
01729 return false;
01730 }
01731
01732 if (!master_act) {
01733 log(Error) << "Can't create SlaveActivity: Master component "<<master_name<<" has no activity set."<<endlog();
01734 return false;
01735 }
01736 }
01737
01738 comps[comp_name].instance = peer;
01739 if ( peer->isRunning() ) {
01740 log(Error) << "Can't change activity of component "<<comp_name<<" since it is still running."<<endlog();
01741 return false;
01742 }
01743
01744 base::ActivityInterface* newact = 0;
01745
01746 if ( act_type == "Activity")
01747 newact = new RTT::Activity(scheduler, priority, period);
01748 else
01749
01750 if ( act_type == "PeriodicActivity" && period != 0.0)
01751 newact = new RTT::extras::PeriodicActivity(scheduler, priority, period);
01752 else
01753 if ( act_type == "NonPeriodicActivity" && period == 0.0)
01754 newact = new RTT::Activity(scheduler, priority, period);
01755 else
01756 if ( act_type == "SlaveActivity" ) {
01757 if ( master_act == 0 )
01758 newact = new extras::SlaveActivity(period);
01759 else {
01760 newact = new extras::SlaveActivity(master_act);
01761 this->getPeer(master_name)->addPeer( peer );
01762 }
01763 }
01764 else
01765 if (act_type == "Activity") {
01766 newact = new Activity(scheduler, priority, period, 0, comp_name);
01767 }
01768 else
01769 if (act_type == "SequentialActivity") {
01770 newact = new SequentialActivity();
01771 }
01772
01773 if (newact == 0) {
01774 log(Error) << "Can't create '"<< act_type << "' for component "<<comp_name<<": incorrect arguments."<<endlog();
01775 return false;
01776 }
01777
01778
01779 assert( peer->isRunning() == false );
01780 delete comps[comp_name].act;
01781 comps[comp_name].act = newact;
01782
01783 return true;
01784 }
01785
01786 bool DeploymentComponent::configure(const std::string& name)
01787 {
01788 return configureFromFile( name, name + ".cpf" );
01789 }
01790
01791 bool DeploymentComponent::configureFromFile(const std::string& name, const std::string& filename)
01792 {
01793 RTT::Logger::In in("DeploymentComponent");
01794 RTT::TaskContext* c;
01795 if ( name == this->getName() )
01796 c = this;
01797 else
01798 c = this->getPeer(name);
01799 if (!c) {
01800 log(Error)<<"No such peer to configure: "<<name<<endlog();
01801 return false;
01802 }
01803
01804 marsh::PropertyLoader pl;
01805 return pl.configure( filename, c, true );
01806 }
01807
01808 FactoryMap& DeploymentComponent::getFactories()
01809 {
01810 return ComponentFactories::Instance();
01811 }
01812
01813 void DeploymentComponent::kickOut(const std::string& config_file)
01814 {
01815 RTT::Logger::In in("DeploymentComponent::kickOut");
01816 RTT::PropertyBag from_file;
01817 RTT::Property<std::string> import_file;
01818 std::vector<std::string> deleted_components_type;
01819
01820
01821 bool failure = false;
01822
01823 marsh::PropertyDemarshaller demarshaller(config_file);
01824 try {
01825 if ( demarshaller.deserialize( from_file ) ){
01826 for (RTT::PropertyBag::iterator it= from_file.begin(); it!=from_file.end();it++) {
01827 if ( (*it)->getName() == "Import" ) continue;
01828 if ( (*it)->getName() == "Include" ) continue;
01829
01830 kickOutComponent( (*it)->getName() );
01831 }
01832 deletePropertyBag( from_file );
01833 }
01834 else {
01835 log(Error)<< "Some error occured while parsing "<< config_file <<endlog();
01836 failure = true;
01837 }
01838 } catch (...)
01839 {
01840 log(Error)<< "Uncaught exception in kickOut() !"<< endlog();
01841 failure = true;
01842 }
01843 }
01844
01845 bool DeploymentComponent::cleanupComponent(RTT::TaskContext *instance)
01846 {
01847 RTT::Logger::In in("DeploymentComponent::cleanupComponent");
01848 bool valid = true;
01849
01850 if (instance) {
01851 if ( instance->getTaskState() <= base::TaskCore::Stopped ) {
01852 OperationCaller<bool(void)> instancecleanup = instance->getOperation("cleanup");
01853 instancecleanup();
01854 log(Info) << "Cleaned up "<< instance->getName() <<endlog();
01855 } else {
01856 log(Error) << "Could not cleanup Component "<< instance->getName() << " (not Stopped)"<<endlog();
01857 valid = false;
01858 }
01859 }
01860 return valid;
01861 }
01862
01863 bool DeploymentComponent::stopComponent(RTT::TaskContext *instance)
01864 {
01865 RTT::Logger::In in("DeploymentComponent::stopComponent");
01866 bool valid = true;
01867
01868 if ( instance ) {
01869 OperationCaller<bool(void)> instancestop = instance->getOperation("stop");
01870 if ( !instance->isRunning() ||
01871 instancestop() ) {
01872 log(Info) << "Stopped "<< instance->getName() <<endlog();
01873 }
01874 else {
01875 log(Error) << "Could not stop loaded Component "<< instance->getName() <<endlog();
01876 valid = false;
01877 }
01878 }
01879 return valid;
01880 }
01881
01882 bool DeploymentComponent::kickOutComponent(const std::string& comp_name)
01883 {
01884 RTT::Logger::In in("DeploymentComponent::kickOutComponent");
01885
01886 RTT::TaskContext* peer = comps.count(comp_name) ? comps[ comp_name ].instance : 0;
01887
01888 if ( !peer ) {
01889 log(Error) << "Component not loaded by this Deployer: "<< comp_name <<endlog();
01890 return false;
01891 }
01892 stopComponent( peer );
01893 cleanupComponent (peer );
01894 unloadComponent( comp_name);
01895
01896
01897 root.removeProperty( root.find( comp_name ) );
01898
01899 return true;
01900 }
01901 }