diff options
Diffstat (limited to 'modules/CIAO/DAnCE/ExecutionManager')
6 files changed, 1144 insertions, 0 deletions
diff --git a/modules/CIAO/DAnCE/ExecutionManager/DAM_Map.cpp b/modules/CIAO/DAnCE/ExecutionManager/DAM_Map.cpp new file mode 100644 index 00000000000..350fb63d331 --- /dev/null +++ b/modules/CIAO/DAnCE/ExecutionManager/DAM_Map.cpp @@ -0,0 +1,122 @@ +#include "DAM_Map.h" +#include "ciao/CIAO_Config.h" +#include "ciao/CIAO_common.h" + +ACE_RCSID (ExecutionManager, + DAM_Map, + "$Id$") + +namespace CIAO +{ + namespace Execution_Manager + { + DAM_Map::DAM_Map (void) + : map_ (CIAO_DEFAULT_MAP_SIZE) + { + } + + size_t + DAM_Map::size (void) + { + return this->map_.current_size (); + } + + bool + DAM_Map::is_plan_available (const ACE_CString &str) + { + CIAO_TRACE("Execution_Manager::DAM_Map::is_plan_available"); + if (this->map_.find (str) == 0) + return true; + + return false; + } + + ::Deployment::DomainApplicationManager_ptr + DAM_Map::fetch_dam_reference (const ACE_CString &str) + { + CIAO_TRACE("Execution_Manager::DAM_Map::fetch_dam_reference"); + if (!this->is_plan_available (str)) + return ::Deployment::DomainApplicationManager::_nil (); + + ::Deployment::DomainApplicationManager_var tmp; + + /// There should be duplicate when assigning a _var to an _var. + int const retval = this->map_.find (str, + tmp); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) CIAO_ExecutionManager: fetch_dam_reference, " + "result from find is [%d] \n", + retval)); + } + + return tmp._retn (); + } + + + bool + DAM_Map::bind_dam_reference ( + const ACE_CString &str, + ::Deployment::DomainApplicationManager_ptr dam) + { + CIAO_TRACE("Execution_Manager::DAM_Map::bind_dam_reference"); + int const retval = + this->map_.rebind (str, + dam); + + if (retval != 0) + return false; + + return true; + } + + + Deployment::DomainApplicationManagers * + DAM_Map::get_dams () + { + CIAO_TRACE("Execution_Manager::DAM_Map::get_dams"); + CORBA::ULong const sz = + this->map_.current_size (); + + // Initialize the list of DomainApplication Managers + Deployment::DomainApplicationManagers_var list; + ACE_NEW_THROW_EX (list, + Deployment::DomainApplicationManagers (sz), + CORBA::NO_MEMORY()); + + // Add the manager to the list + list->length (sz); + + Iterator end = + this->map_.end (); + + CORBA::ULong i = 0; + + for (Iterator b = + this->map_.begin (); b != end; ++b) + { + list [i] = + Deployment::DomainApplicationManager::_duplicate ((*b).int_id_.in ()); + + ++i; + } + + return list._retn (); + } + + bool + DAM_Map::unbind_dam (const ACE_CString &str) + { + CIAO_TRACE("Execution_Manager::DAM_Map::unbind_dam"); + int const retval = + this->map_.unbind (str); + + if (retval != 0) + return false; + + return true; + } + } +} diff --git a/modules/CIAO/DAnCE/ExecutionManager/DAM_Map.h b/modules/CIAO/DAnCE/ExecutionManager/DAM_Map.h new file mode 100644 index 00000000000..d69c9d10e9a --- /dev/null +++ b/modules/CIAO/DAnCE/ExecutionManager/DAM_Map.h @@ -0,0 +1,72 @@ +/*======================================================================= + * + * @file DAM_Map.h + * + * $Id$ + * + * @brief Map of DomainApplicationManager to UUID's + * + * @author Bala Natarajan <bala @ dre.vanderbilt.edu> + * + *======================================================================*/ +#ifndef CIAO_DAM_MAP_H +#define CIAO_DAM_MAP_H +#include /**/ "ace/pre.h" + +#include "ciao/Deployment_DomainApplicationManagerC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Null_Mutex.h" +#include "ace/Hash_Map_Manager.h" +#include "ace/SString.h" + +namespace CIAO +{ + namespace Execution_Manager + { + /** + * @class DAM_Map + * + * @brief Map of DomainApplicationManager to ACE_CStrings + * + */ + class DAM_Map + { + public: + DAM_Map (void); + + bool is_plan_available (const ACE_CString &str); + + ::Deployment::DomainApplicationManager_ptr + fetch_dam_reference (const ACE_CString &str); + + bool bind_dam_reference ( + const ACE_CString &str, + ::Deployment::DomainApplicationManager_ptr tmp); + + Deployment::DomainApplicationManagers * + get_dams (); + + bool unbind_dam (const ACE_CString &str); + + size_t size (void); + + private: + typedef + ACE_Hash_Map_Manager_Ex < ACE_CString, + ::Deployment::DomainApplicationManager_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> MAP; + typedef MAP::iterator Iterator; + + MAP map_; + }; + } +} + +#include /**/ "ace/post.h" +#endif /*CIAO_DAM_MAP_H*/ diff --git a/modules/CIAO/DAnCE/ExecutionManager/ExecutionManager.mpc b/modules/CIAO/DAnCE/ExecutionManager/ExecutionManager.mpc new file mode 100644 index 00000000000..736eaa5f885 --- /dev/null +++ b/modules/CIAO/DAnCE/ExecutionManager/ExecutionManager.mpc @@ -0,0 +1,16 @@ +// -*- MPC -*- +// $Id$ + +project(ExecutionManager): ciao_server_dnc, dance_extension_stub, ciao_domainapplicationmanager_dnc, ciao_executionmanager_stub { + exename = Execution_Manager + + IDL_Files { + } + + Source_Files { + ../Interfaces/ExecutionManagerDaemonS.cpp + Execution_Manager.cpp + Execution_Manager_Impl.cpp + DAM_Map.cpp + } +} diff --git a/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager.cpp b/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager.cpp new file mode 100644 index 00000000000..c7b5df7b96a --- /dev/null +++ b/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager.cpp @@ -0,0 +1,247 @@ +//--*C++*-- +// $Id$ + +#include "Execution_Manager_Impl.h" + +// Include Name Service header +#include "orbsvcs/CosNamingC.h" +#include "tao/Utils/Implicit_Deactivator.h" + +#include "ace/SString.h" +#include "ace/Read_Buffer.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stdio.h" + +namespace CIAO +{ + namespace Execution_Manager + { + const char *ior_file_name_ = "executionManager.ior"; + const char *init_file_name = "deployment.dat"; + const char *pid_file_name_ = 0; + static bool register_with_ns_ = false; + static bool write_to_ior_ = false; + + bool + parse_args (int argc, char *argv[]) + { + ACE_Get_Opt get_opts (argc, argv, "o:i:np:"); + int c; + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + write_to_ior_ = true; + ior_file_name_ = get_opts.opt_arg (); + break; + case 'i': + init_file_name = get_opts.opt_arg (); + break; + case 'n': + register_with_ns_ = true; + break; + case 'p': + pid_file_name_ = get_opts.opt_arg (); + break; + case '?': // display help for use of the server. + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s\n" + "-o <ior_output_file>\n" + "-i <installation data filename>\n" + "-n <use naming service>\n" + "-p <filename to output the process id>\n" + "\n", + argv [0]), + false); + } + + return true; + } + + bool + write_ior_file (CORBA::ORB_ptr orb, + CIAO::ExecutionManagerDaemon_ptr obj) + { + CORBA::String_var ior = + orb->object_to_string (obj); + + FILE* ior_output_file_ = + ACE_OS::fopen (ior_file_name_, "w"); + + if (ior_output_file_) + { + ACE_OS::fprintf (ior_output_file_, + "%s", + ior.in ()); + ACE_OS::fclose (ior_output_file_); + } + else + return false; + + return true; + } + + void + write_pid (void) + { + if (pid_file_name_ == 0) + return; + + FILE* pid_file = ACE_OS::fopen (pid_file_name_, "w"); + + if (pid_file) + { + ACE_OS::fprintf (pid_file, + "%i", + ACE_OS::getpid ()); + ACE_OS::fclose (pid_file); + } + } + + bool + register_with_ns (CORBA::ORB_ptr orb, + CIAO::ExecutionManagerDaemon_ptr obj) + { + // Naming Service related operations + CORBA::Object_var naming_context_object = + orb->resolve_initial_references ("NameService"); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_context_object.in ()); + + // Initialize the Naming Sequence + CosNaming::Name name (1); + name.length (1); + + // String dup required for MSVC6 + name[0].id = CORBA::string_dup ("ExecutionManager"); + + // Register the servant with the Naming Service + try + { + // Register the servant with the Naming Service + naming_context->bind (name, obj); + } + catch (CosNaming::NamingContext::AlreadyBound &) + { + ACE_DEBUG ((LM_DEBUG, "Execution_Manager.cpp: Name already bound, rebinding....\n")); + naming_context->rebind (name, obj); + } + + return true; + } + + int + run_main (int argc, char *argv[]) + { + + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, + argv, + ""); + + if (!parse_args (argc, argv)) + return -1; + + // Get reference to Root POA. + CORBA::Object_var obj + = orb->resolve_initial_references ("RootPOA"); + + PortableServer::POA_var poa = + PortableServer::POA::_narrow (obj.in ()); + + + if (CORBA::is_nil (poa.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) CIAO_ExecutionManager: " + "Nil POA panic error, returning \n"), + -1); + + // Create and install the CIAO Daemon servant + Execution_Manager_Impl *daemon_servant = 0; + ACE_NEW_RETURN (daemon_servant, + Execution_Manager_Impl(orb.in (), + poa.in (), + init_file_name), + -1); + + // Implicit activation + PortableServer::ServantBase_var safe_daemon (daemon_servant); + + CIAO::ExecutionManagerDaemon_var daemon = + daemon_servant->_this (); + + TAO::Utils::Implicit_Deactivator de (daemon_servant); + bool retval = false; + + if (register_with_ns_) + { + retval = + register_with_ns (orb.in (), + daemon.in ()); + } + + if (write_to_ior_) + { + retval = + write_ior_file (orb.in (), + daemon.in ()); + } + + if (!retval) + return -1; + + // Activate POA manager + PortableServer::POAManager_var mgr = + poa->the_POAManager (); + + if (mgr.in () == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) CIAO_ExecutionManager: " + "Nil POA Manager error, returning \n"), + -1); + + mgr->activate (); + + // End Deployment part + ACE_DEBUG ((LM_DEBUG, + "CIAO_ExecutionManager is running...\n")); + + write_pid (); + + // Run the main event loop for the ORB. + orb->run (); + + // Forget the pointer. The POA will take care of it during + // destroy. + (void) de.release (); + + poa->destroy (1, + 1); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("CIAO_ExecutionManager::main\t\n"); + return -1; + } + + ACE_DEBUG ((LM_DEBUG, + "CIAO_ExecutionManager has closed\n")); + return 0; + } + + } +} + +int +main (int argc, char *argv[]) +{ + return CIAO::Execution_Manager::run_main (argc, + argv); +} diff --git a/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager_Impl.cpp b/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager_Impl.cpp new file mode 100644 index 00000000000..8a93b2f5ef0 --- /dev/null +++ b/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager_Impl.cpp @@ -0,0 +1,512 @@ +// $Id$ + +#include "Execution_Manager_Impl.h" +#include "ciao/CIAO_common.h" +#include "DomainApplicationManager/DomainApplicationManager_Impl.h" + +ACE_RCSID (ExecutionManager, + Execution_Manager_Impl, + "$Id$") + +namespace CIAO +{ + namespace Execution_Manager + { + Execution_Manager_Impl::Execution_Manager_Impl ( + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + const char * init_file) + : orb_ (CORBA::ORB::_duplicate (orb)) + , poa_ (PortableServer::POA::_duplicate (poa)) + , init_file_ (init_file) + { + } + + Execution_Manager_Impl::~Execution_Manager_Impl (void) + { + } + + Deployment::DomainApplicationManager_ptr + Execution_Manager_Impl::preparePlan ( + const Deployment::DeploymentPlan &plan, + CORBA::Boolean) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::PlanError, + Deployment::StartError + )) + { + CIAO_TRACE("Execution_Manager::Execution_Manager_Impl::preparePlan"); + + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) Domain Application Manager " + "invoked CIAO_Execution_Manager: preparePlan \n")); + + // There is a Domain Application Manager already existing + // for this DeploymentPlan. + // No need to create a new DAM. Hence pass the + // reference that is already created. + // + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) calling this->man_.is_plan_available()...\n")); + if (this->map_.is_plan_available (plan.UUID.in ())) + { + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) Plan is already available; " + "calling this->man_.fetch_dam_reference()...\n")); + + return this->map_.fetch_dam_reference (plan.UUID.in ()); + } + else + { + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) Plan wasn't already available\n")); + } + + // We are about to begin working on a new DeploymentPlan. + // Create a DAM servant, which will be populated + // to be sent back to the PlanLauncher. + // + CIAO::DomainApplicationManager_Impl *dam_servant = 0; + + // Create a new Domain Application Manager servant + // to be sent back to the Plan Launcher. + // + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) About to instantiate CIAO::DomainApplicationManager_Impl\n")); + ACE_NEW_THROW_EX ( + dam_servant, + CIAO::DomainApplicationManager_Impl ( + this->orb_.in (), + this->poa_.in (), + ::Deployment::TargetManager::_nil (), + this, // a plain C++ pointer + plan, + this->init_file_.c_str ()), + CORBA::NO_MEMORY ()); + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) Instantiated CIAO::DomainApplicationManager_Impl\n")); + + // Sanity check for NULL pointer + // Should we throw an exception here? + // We have exceptions like PlanError or StartError at + // our disposal already in this function. + // Why did the creation of DAM fail in the first place? + // + + // Standard owner transfer mechanisms. + // + PortableServer::ServantBase_var safe_daemon (dam_servant); + + // Calling the init function on the DAM. + // This function will split the plan into node specific + // plans, so that those plans can be sent off to individual + // Node Application Managers. + // + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) About to init...\n")); + dam_servant->init (); + + // This is a wrong exception to be thrown here. + // We already had a DAM servant, the DAM servant is + // not NIL any more. + // We need to throw the right exception here. + // + + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) About to set uuid on DAM...\n")); + dam_servant->set_uuid (plan.UUID.in ()); + + Deployment::DomainApplicationManager_var dam = + dam_servant->_this (); + + /// @@ TODO:Need to check the return value...... + /// + this->map_.bind_dam_reference ( + plan.UUID.in (), + Deployment::DomainApplicationManager::_duplicate (dam.in ())); + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) Bound DAM reference...\n")); + + // Return the ApplicationManager instance + return dam._retn (); + } + + Deployment::DomainApplicationManagers * + Execution_Manager_Impl::getManagers () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + CIAO_TRACE("Execution_Manager::Execution_Manager_Impl::getManagers"); + + // TODO Need to check the return value. + // + return this->map_.get_dams (); + } + + Deployment::DomainApplicationManager_ptr + Execution_Manager_Impl::getManager (const char * plan_uuid) + ACE_THROW_SPEC ((CORBA::SystemException, Deployment::PlanNotExist)) + { + return this->map_.fetch_dam_reference (plan_uuid); + } + + void + Execution_Manager_Impl::destroyManager ( + Deployment::DomainApplicationManager_ptr manager) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)) + { + CIAO_TRACE("Execution_Manager::Execution_Manager_Impl::destroyManagers"); + try + { + ::Deployment::DeploymentPlan_var plan = + manager->getPlan (); + + // What if we still have components running within this plan? + // + (void) this->map_.unbind_dam (plan->UUID.in ()); + + // Where does the POA deactivate happen? + // + manager->destroyManager (); + +#if 0 + PortableServer::ObjectId_var oid = + this->poa_->reference_to_id (manager); + + this->poa_->deactivate_object (oid.in ()); +#endif /*if 0*/ + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "Execution_Manager_Impl::destroyManager\t\n"); + throw Deployment::StopError (); + } + } + + + void + Execution_Manager_Impl::destroyManagerByPlan ( + const char * plan_uuid) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)) + { + CIAO_TRACE("Execution_Manager::Execution_Manager_Impl::destroyManagerByPlan"); + try + { + // Get DomainApplicationManager first + if (! this->map_.is_plan_available (plan_uuid)) + { + ACE_ERROR ((LM_ERROR, + "Execution_Manager_Impl::destroyManagerByPlan - " + "Invalid plan uuid [%s]\n", plan_uuid)); + throw Deployment::StopError (); + } + + Deployment::DomainApplicationManager_var + dam = this->map_.fetch_dam_reference (plan_uuid); + + // Get the plan + Deployment::DeploymentPlan_var plan = dam->getPlan (); + + // If any component is still running, then we return. + CORBA::ULong const inst_lenth = plan->instance.length (); + for (CORBA::ULong i = 0; i < inst_lenth; ++i) + { + if (this->is_component_running (plan->instance[i].name.in (), + plan_uuid)) + return; + } + + (void) this->map_.unbind_dam (plan->UUID.in ()); + + // Where does the POA deactivate happen? + // + dam->destroyManager (); + +#if 0 + PortableServer::ObjectId_var oid = + this->poa_->reference_to_id (manager); + + this->poa_->deactivate_object (oid.in ()); +#endif /*if 0*/ + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "Execution_Manager_Impl::destroyManager\t\n"); + throw Deployment::StopError (); + } + } + + + void + Execution_Manager_Impl::shutdown () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + CIAO_TRACE("Execution_Manager::Execution_Manager_Impl::shutdown"); + // Shutdown the ORB on which it is runing + this->orb_->shutdown (0); + } + + void + Execution_Manager_Impl::perform_redeployment ( + const Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::PlanError, + ::Deployment::InstallationFailure, + ::Deployment::UnknownImplId, + ::Deployment::ImplEntryPointNotFound, + ::Deployment::InvalidConnection, + ::Deployment::InvalidProperty, + ::Components::RemoveFailure)) + { + CIAO_TRACE ("CIAO::Execution_Manager_Impl::perform_redeployment"); + + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) Dynamic Redeployment: " + "invoked CIAO::Execution_Manager_Impl::perform_redeployment \n")); + + Deployment::DomainApplicationManager_var dam; + + if (this->map_.is_plan_available (plan.UUID.in ())) + { + dam = this->map_.fetch_dam_reference (plan.UUID.in ()); + } + else + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) ExecutionManager_Impl.cpp -" + "CIAO::Execution_Manager_Impl::perform_redeployment -" + "Invalid plan uuid: %s\n", plan.UUID.in ())); + throw Deployment::PlanError ( + "Execution_Manager_Impl::perform_redeployment", + "Invalid plan uuid specified."); + } + + try + { + // Call perform_redeployment() on the DAM, which will do the + // actual redeployment and reconfiguration on the dommain level. + dam->perform_redeployment (plan); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "Execution_Manager_Impl::perform_redeployment\t\n"); + throw; + } + } + + Deployment::DeploymentPlan * + Execution_Manager_Impl::getPlan (const char * plan_uuid) + ACE_THROW_SPEC ((::CORBA::SystemException)) + { + Deployment::DomainApplicationManager_var dam; + + if (this->map_.is_plan_available (plan_uuid)) + { + dam = this->map_.fetch_dam_reference (plan_uuid); + } + else + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) ExecutionManager_Impl.cpp -" + "CIAO::Execution_Manager_Impl::getPlan -" + "Invalid plan uuid: %s\n", plan_uuid)); + throw ::CORBA::BAD_PARAM (); + } + + try + { + return dam->getPlan (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Execution_Manager_Impl::getPlan\t\n"); + throw; + } + } + + void + Execution_Manager_Impl::finalize_global_binding ( + const Component_Binding_Info & binding, + CORBA::Boolean add_or_remove) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Deployment::InvalidConnection)) + { + ACE_DEBUG ((LM_DEBUG, + "Execution_Manage::finalizing global bindings.\n")); + + // Find the NodeApplication hosting the component, and then call + // <finishLaunch> on it + try + { + Deployment::NodeApplication_var + node_app = this->find_node_application (binding); + + if (CORBA::is_nil (node_app.in ())) + { + ACE_ERROR ((LM_ERROR, + "Execution_Manager_Impl::finalize_global_binding - " + "nil NodeApplication object reference.\n")); + throw Deployment::InvalidConnection (); + } + + node_app->finishLaunch (binding.providedReference_.in (), + true, // start + add_or_remove); + + // Update the internal shared component list + if (add_or_remove) + this->add_shared_component (binding); + else + this->remove_shared_component (binding); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "Execution_Manager_Impl::finalize_global_binding\t\n"); + throw Deployment::InvalidConnection (); + } + } + + void + Execution_Manager_Impl::passivate_shared_components ( + const Component_Binding_Info & binding) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + Deployment::StartError)) + { + ACE_DEBUG ((LM_DEBUG, + "Execution_Manage::passivate shared components.\n")); + + // Find the NodeApplication hosting the component, and then call + // <finishLaunch> on it + try + { + Deployment::NodeApplication_var + node_app = this->find_node_application (binding); + + if (CORBA::is_nil (node_app.in ())) + { + ACE_ERROR ((LM_ERROR, + "Execution_Manager_Impl::passivate_shared_components - " + "nil NodeApplication object reference.\n")); + throw Deployment::StartError (); + } + + node_app->passivate_component (binding.name_.c_str ()); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "Execution_Manager_Impl::passivate_shared_components\t\n"); + throw Deployment::StartError (); + } + } + + void + Execution_Manager_Impl::activate_shared_components ( + const Component_Binding_Info & binding) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + Deployment::StartError)) + { + ACE_DEBUG ((LM_DEBUG, + "Execution_Manage::activate shared components.\n")); + + // Find the NodeApplication hosting the component, and then call + // <ciao_activate> on it + try + { + Deployment::NodeApplication_var + node_app = this->find_node_application (binding); + + if (CORBA::is_nil (node_app.in ())) + { + ACE_ERROR ((LM_ERROR, + "Execution_Manager_Impl::activate_shared_components - " + "nil NodeApplication object reference.\n")); + throw Deployment::StartError (); + } + + node_app->activate_component (binding.name_.c_str ()); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "Execution_Manager_Impl::passivate_shared_components\t\n"); + throw Deployment::StartError (); + } + } + + + Deployment::NodeApplication_ptr + + Execution_Manager_Impl:: + find_node_application (const Component_Binding_Info & binding) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Deployment::InvalidConnection)) + { + // Find the DAM based on plan_UUID + Deployment::DomainApplicationManager_var dam; + + if (this->map_.is_plan_available (binding.plan_uuid_)) + { + dam = this->map_.fetch_dam_reference (binding.plan_uuid_); + } + else + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) ExecutionManager_Impl.cpp -" + "CIAO::Execution_Manager_Impl::find_node_application -" + "Invalid plan uuid: %s\n", binding.plan_uuid_.c_str ())); + throw ::CORBA::BAD_PARAM (); + } + + // Find the NA based on the NodeName field of the binding + // This is a CORBA call on the DAM + Deployment::NodeApplication_var + node_app = dam->get_node_app (binding.node_.c_str ()); + + if (CORBA::is_nil (node_app.in ())) + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) ExecutionManager_Impl.cpp -" + "CIAO::Execution_Manager_Impl::find_node_application -" + "Invalid node name: %s!\n", binding.node_.c_str ())); + throw ::CORBA::BAD_PARAM (); + } + + return node_app._retn (); + } + + void + Execution_Manager_Impl:: + add_shared_component (const Component_Binding_Info & comp) + { + this->shared_components_.insert (comp); + } + + void + Execution_Manager_Impl:: + remove_shared_component (const Component_Binding_Info & comp) + { + this->shared_components_.remove (comp); + } + + bool + Execution_Manager_Impl:: + is_component_running (const char * name, const char * plan_uuid) + { + for (ACE_Unbounded_Set<Component_Binding_Info>::iterator + iter = this->shared_components_.begin (); + iter != this->shared_components_.end (); + ++iter) + { + if (ACE_OS::strcmp ((*iter).name_.c_str (), name) == 0 && + ACE_OS::strcmp ((*iter).plan_uuid_.c_str (), plan_uuid) == 0) + return true; + } + + return false; + } + } +} diff --git a/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager_Impl.h b/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager_Impl.h new file mode 100644 index 00000000000..cf674d37fe9 --- /dev/null +++ b/modules/CIAO/DAnCE/ExecutionManager/Execution_Manager_Impl.h @@ -0,0 +1,175 @@ +/*======================================================================= + * + * @file Execution_Manager_Impl.h + * + * $Id$ + * + * @brief This file contains implementation for + * Deployment::ExecutionManager interface. + * + * @author Arvind S. Krishna <arvindk@dre.vanderbilt.edu> + * @auther Tao Lu <lu@dre.vanderbilt.edu> + * + *======================================================================*/ + +#ifndef CIAO_EXECUTION_MANAGER_IMPL_H +#define CIAO_EXECUTION_MANAGER_IMPL_H +#include /**/ "ace/pre.h" + +#include "Interfaces/ExecutionManagerDaemonS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "DAM_Map.h" +#include "ace/SString.h" +#include "ciao/Deployment_common.h" + +namespace CIAO +{ + namespace Execution_Manager + { + /** + * + * @class Execution_Manager_Impl + * + * @brief This class implements the + * ExecutionManger. ExecutionManager starts the execution process + * after the planning stage. + * + */ + class Execution_Manager_Impl + : public virtual POA_CIAO::ExecutionManagerDaemon + { + public: + /// Constructor + Execution_Manager_Impl (CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + const char * init_file); + + /// Template methods from ExecutionManagerDaemon, please see + /// $CIAO_ROOT/ciao/Deployment.idl for documentation + virtual Deployment::DomainApplicationManager_ptr + preparePlan (const Deployment::DeploymentPlan & plan, + CORBA::Boolean commitResources) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::PlanError, + Deployment::StartError)); + + virtual Deployment::DomainApplicationManagers * + getManagers () + ACE_THROW_SPEC ((CORBA::SystemException)); + + // Below method is CIAO specific extension + virtual Deployment::DomainApplicationManager_ptr + getManager (const char * plan_uuid) + ACE_THROW_SPEC ((CORBA::SystemException, Deployment::PlanNotExist)); + + virtual void + destroyManager (Deployment::DomainApplicationManager_ptr manager) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)); + + // Below method is CIAO specific extension, please see the IDL + // definition for more details. + virtual void + destroyManagerByPlan (const char * plan_uuid) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::StopError)); + + virtual void shutdown () + ACE_THROW_SPEC ((CORBA::SystemException)); + + // The input parameter is a *new_plan* which has the + // same UUID of the existing running plan. + virtual void + perform_redeployment ( + const Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::PlanError, + ::Deployment::InstallationFailure, + ::Deployment::UnknownImplId, + ::Deployment::ImplEntryPointNotFound, + ::Deployment::InvalidConnection, + ::Deployment::InvalidProperty, + ::Components::RemoveFailure)); + + virtual Deployment::DeploymentPlan * getPlan ( + const char * plan_uuid) + ACE_THROW_SPEC ((::CORBA::SystemException)); + + /// ****************** C++ Methods ************************* + + /// If input <add_connection> is true, then it will add new + /// connections which are across different assemblies. Otherwise + /// it will remove the specified connections of this component. + /// + /// @@GD: Later we can add another method which could accept + /// a list of bindings and do the batch job. + virtual void finalize_global_binding ( + const Component_Binding_Info & binding, + CORBA::Boolean add_connection) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Deployment::InvalidConnection)); + + virtual void passivate_shared_components ( + const Component_Binding_Info & binding) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + virtual void activate_shared_components ( + const Component_Binding_Info & binding) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + /// Add shared component information. + /// This call will be made by DomainApplicationManager. + virtual void + add_shared_component (const Component_Binding_Info & binding); + + /// Remove shared component + virtual void + remove_shared_component (const Component_Binding_Info & binding); + + /// If the input component <name> was found in the internal + /// cached shared component list, and the plan_uuid also matches, + /// then this member function returns <true>, otherwise it + /// returns <false>. + virtual bool + is_component_running (const char * name, const char * plan_uuid); + + protected: + /// Return the NodeApplication hosting the given biding + virtual Deployment::NodeApplication_ptr + find_node_application (const Component_Binding_Info & binding) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Deployment::InvalidConnection)); + + protected: + /// Destructor. + virtual ~Execution_Manager_Impl (void); + + /// Cached ORB pointer + CORBA::ORB_var orb_; + + /// Cached POA pointer + PortableServer::POA_var poa_; + + /// Path to the initialization file + ACE_CString const init_file_; + + /// A map which caches the DomainApplicationManager object ref. + DAM_Map map_; + + /// A set of shared components and their location info. + ACE_Unbounded_Set<Component_Binding_Info> shared_components_; + }; + } +} + +#include /**/ "ace/post.h" +#endif /* EXECUTIONMANAGER_IMPL_H */ |