// $Id$ #include "DomainApplicationManager_Impl.h" #include "ExecutionManager/Execution_Manager_Impl.h" #include "ciao/NodeApplicationManagerC.h" #include "ace/Null_Mutex.h" #include "ace/OS_NS_string.h" #include "ace/SString.h" #include "ace/Assert.h" #if !defined (__ACE_INLINE__) # include "DomainApplicationManager_Impl.inl" #endif /* __ACE_INLINE__ */ CIAO::DomainApplicationManager_Impl:: DomainApplicationManager_Impl (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, Deployment::TargetManager_ptr manager, Execution_Manager::Execution_Manager_Impl * em, const Deployment::DeploymentPlan & plan, const char * deployment_file) ACE_THROW_SPEC ((CORBA::SystemException)) : orb_ (CORBA::ORB::_duplicate (orb)), poa_ (PortableServer::POA::_duplicate (poa)), execution_manager_ (em), // a plain C++ pointer target_manager_ (Deployment::TargetManager::_duplicate (manager)), // object ref plan_ (plan), num_child_plans_ (0), // @@ (OO) The default size for an ACE_Hash_Map_Mapanger is quiet // large. The maximum size of an ACE_Hash_Map_Manager is // also fixed, i.e. it does not grow dynamically on demand. // Make sure the default size of artifact_map_ is // appropriate for your needs. You may also want to make // the size configurable at compile-time, at least. // // Need to initialize chained artifacts here. // deployment_file_ (CORBA::string_dup (deployment_file)), deployment_config_ (orb), is_redeployment_ (false), esd_ (0) { ACE_DECLARE_NEW_CORBA_ENV; ACE_NEW_THROW_EX (this->all_connections_, Deployment::Connections (), CORBA::NO_MEMORY ()); ACE_NEW_THROW_EX (this->shared_, Deployment::ComponentPlans (), CORBA::NO_MEMORY ()); ACE_CHECK; for (CORBA::ULong i = 0; i < this->plan_.infoProperty.length (); ++i) { if (ACE_OS::strcmp (this->plan_.infoProperty[i].name.in (), "CIAOEvents") != 0) continue; this->plan_.infoProperty[0].value >>= this->esd_; break; } } CIAO::DomainApplicationManager_Impl::~DomainApplicationManager_Impl () { if (CIAO::debug_level () > 1) { ACE_DEBUG ((LM_DEBUG, "DomainApplicationManager destroyed\n")); } } Deployment::NodeApplication_ptr CIAO::DomainApplicationManager_Impl:: get_node_app (const char * node_name) ACE_THROW_SPEC ((::CORBA::SystemException, ::Deployment::NoSuchName)) { // Get the NodeApplication object reference. ACE_Hash_Map_Entry *entry = 0; if (this->artifact_map_.find (node_name, entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::get_node_app -" "ERROR while finding the node application " "for the node [%s] \n", node_name)); ACE_THROW (Deployment::NoSuchName ()); } return Deployment::NodeApplication::_duplicate ( entry->int_id_.node_application_.in ()); } void CIAO::DomainApplicationManager_Impl:: init (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, Deployment::ResourceNotAvailable, Deployment::StartError, Deployment::PlanError)) { ACE_TRY { //Deployment::DnC_Dump::dump (this->plan_); /* //====================================== // Dump the contents of infoProperty to a XML file if (CIAO::debug_level () > 1) { CIAO::DAnCE::ServerResource *sr = 0; this->plan_.infoProperty[0].value >>= sr; Config_Handlers::SRD_Handler reverse_handler (sr); Config_Handlers::XML_Helper the_helper; xercesc::DOMDocument *the_xsc (the_helper.create_dom ("CIAO:ServerResources", "http://www.dre.vanderbilt.edu/ServerResources")); ServerResources (*reverse_handler.srd_xsc (), the_xsc); // write out the result the_helper.write_DOM (the_xsc, "output.srd"); } */ //====================================== // (1) Call get_plan_info() method to get the total number // of child plans and list of NodeManager names, and // (2) Check the validity of the global deployment plan. if (! this->get_plan_info ()) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::init -" "ERROR while calling get_plan_info () \n")); ACE_TRY_THROW (Deployment::PlanError ()); } // Call split_plan() if (! this->split_plan ()) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::init -" "ERROR while calling split_plan () \n")); ACE_TRY_THROW (Deployment::PlanError ()); } // Invoke preparePlan on each NodeManager by giving child plan. for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) { // Get the NodeManager object reference. ::Deployment::NodeManager_var my_node_manager = this->deployment_config_.get_node_manager (this->node_manager_names_[i].c_str ()); // Get the child deployment plan reference. ACE_Hash_Map_Entry *entry; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::init -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_TRY_THROW (Deployment::PlanError ()); } Chained_Artifacts & artifacts = entry->int_id_; // Call preparePlan() method on the NodeManager with the // corresponding child plan as input, which returns a // NodeApplicationManager object reference. Deployment::ApplicationManager_var tmp_app_manager = my_node_manager->preparePlan (artifacts.child_plan_.in () ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; Deployment::NodeApplicationManager_var app_manager = Deployment::NodeApplicationManager::_narrow (tmp_app_manager.in () ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; if (CORBA::is_nil (app_manager.in ())) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::init -" "ERROR while narroing the NAM " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("DomainAppMgr::init () received a nil \ reference for NodeApplicationManager\n"); ACE_DEBUG ((LM_DEBUG, error.c_str ())); ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl:init", error.c_str ())); } ACE_TRY_CHECK; // Cache the NodeApplicationManager object reference. artifacts.node_application_manager_ = app_manager._retn (); } } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::init\t\n"); ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } bool CIAO::DomainApplicationManager_Impl:: get_plan_info (void) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::get_plan_info"); // Read the deployment.dat file and get to know the different nodes // that are present in the deployment domain. // We should be able to replace this way, by parsing the domain // descriptor to get to know more on the domain. // if ( this->deployment_config_.init (this->deployment_file_) == -1 ) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::get_plan_info -" "ERROR while trying to initialize after reading " "deployment DAT file \n")); return 0; } // Error: If there are no nodes in the plan => No nodes to deploy the // components const CORBA::ULong length = this->plan_.instance.length (); if (length == 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::get_plan_info -" "ERROR while trying to get the total instances to " "be deployed \n")); return false; } // Copy the name of the node in the plan on to the node manager // array, Making sure that duplicates are not added. // // OPTIMIZATION: // We can parse the domain descriptor and the size of the node // data structure is the size of the num_plans and // the individual node names need to be entered into the // node_manager_map. // int num_plans = 0; this->node_manager_names_.clear (); for (CORBA::ULong index = 0; index < length; index ++) { bool matched = false; const CORBA::ULong number_node_managers = this->node_manager_names_.size (); for (CORBA::ULong i = 0; i < number_node_managers; ++i) // If a match is found do not add it to the list of unique // node names if (ACE_OS::strcmp (this->plan_.instance [index].node.in (), (this->node_manager_names_ [i]).c_str ()) == 0) { // Break out -- Duplicates found matched = true; break; } if (! matched) { // Check if there is a corresponding NodeManager instance existing // If not present return false ::Deployment::NodeManager_var mgr = this->deployment_config_.get_node_manager (this->plan_.instance [index].node.in ()); if (CORBA::is_nil (mgr.in ())) return false; /* Failure */ // Add this unique node_name to the list of NodeManager names this->node_manager_names_.push_back (this->plan_.instance [index].node.in ()); // Increment the number of plans ++num_plans; } } // Set the length of the Node Managers // // why cannot we use the provate variable in the above "for" loop? // this->num_child_plans_ = num_plans; // Indicate success return true; } //@@ We should ask those spec writers to look at the code below, hopefully // They will realize some thing. int CIAO::DomainApplicationManager_Impl:: split_plan (void) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::split_plan"); // Initialize the total number of child deployment plans specified // by the global plan. CORBA::ULong i; for ( i = 0; i < this->num_child_plans_; ++i) { ::Deployment::DeploymentPlan_var tmp_plan; ACE_NEW_RETURN (tmp_plan, ::Deployment::DeploymentPlan, 0); // Construct the UUID for the child plan. // Currently, this UUID consists of: // The global UUID for the parent plan + the name of the node the // child plan is to be installed on. ACE_CString child_uuid (this->plan_.UUID.in ()); child_uuid += "@"; child_uuid += this->node_manager_names_[i]; tmp_plan->UUID = CORBA::string_dup (child_uuid.c_str ()); tmp_plan->implementation.length (0); tmp_plan->instance.length (0); tmp_plan->connection.length (0); tmp_plan->externalProperty.length (0); tmp_plan->dependsOn.length (0); tmp_plan->artifact.length (0); // @@ There is an optimization point here, since we really don't have to // pass the entire CIAOServerResources into each individual child plan. tmp_plan->infoProperty = this->plan_.infoProperty; //tmp_plan->infoProperty[0].name = CORBA::string_dup ("CIAOServerResource"); //tmp_plan->infoProperty[0].value = this->plan_.infoProperty[0].value; Chained_Artifacts artifacts; // Fill in the child_plan_ field, relinquishing ownership artifacts.child_plan_ = tmp_plan._retn (); // Fill in the node_manager_ field. artifacts.node_manager_ = this->deployment_config_.get_node_manager (this->node_manager_names_[i].c_str ()); ACE_Hash_Map_Entry *entry = 0; if (this->artifact_map_.find (node_manager_names_[i], entry) == 0) artifacts.old_child_plan_ = (entry->int_id_).child_plan_; else artifacts.old_child_plan_ = 0; // In case we are doing redeployment, rebind will help replace the // old child plan with the new child plan. this->artifact_map_.rebind (node_manager_names_[i], artifacts); } // (1) Iterate over the field of the global DeploymentPlan // structure. // (2) Retrieve the necessary information to contruct the node-level // plans one by one. for ( i = 0; i < (this->plan_.instance).length (); ++i) { // @@TODO Fill in the child deployment plan in the map. // If the component instance already exists in the child plan, // then we overwrite the existing instance, since the new instance // might have different resource usage requirements. // Get the instance deployment description const ::Deployment::InstanceDeploymentDescription & my_instance = (this->plan_.instance)[i]; // Find the corresponding child deployment plan entry in // the hash map for this instance. ACE_Hash_Map_Entry *entry = 0; if (this->artifact_map_.find (ACE_CString (my_instance.node.in ()), entry) != 0) return 0; // no valid name found. // Get the child plan. ::Deployment::DeploymentPlan_var &child_plan = (entry->int_id_).child_plan_; // Fill in the contents of the child plan entry. // Append the "MonolithicDeploymentDescriptions implementation" // field with a new "implementation", which is specified by the // field of entry. NOTE: The // field needs to be changed accordingly. const ::Deployment::MonolithicDeploymentDescription & my_implementation = (this->plan_.implementation)[my_instance.implementationRef]; // Deployment::DnC_Dump::dump (this->plan_); //Deployment::DnC_Dump::dump ( (this->plan_.implementation)[my_instance.implementationRef]); //ACE_DEBUG ((LM_DEBUG, "My implementation")); //Deployment::DnC_Dump::dump (my_implementation); CORBA::ULong index_imp = child_plan->implementation.length (); child_plan->implementation.length (++index_imp); child_plan->implementation[index_imp-1] = my_implementation; // Initialize with the correct sequence length. CORBA::ULongSeq ulong_seq; ulong_seq.length (my_implementation.artifactRef.length ()); // Append the "ArtifactDeploymentDescriptions artifact" field // with some new "artifacts", which is specified by the // sequence of entry. const CORBA::ULong impl_length = my_implementation.artifactRef.length (); for (CORBA::ULong iter = 0; iter < impl_length; iter ++) { CORBA::ULong artifact_ref = my_implementation.artifactRef[iter]; // Fill in the field of the child plan CORBA::ULong index_art = child_plan->artifact.length (); child_plan->artifact.length (++index_art); child_plan->artifact[index_art-1] = (this->plan_.artifact)[artifact_ref]; // Fill in the field of the MonolithicDeploymentDescription ulong_seq[iter] = index_art-1; } // Change the field of the "implementation". child_plan->implementation[index_imp-1].artifactRef = ulong_seq; // Append the "InstanceDeploymentDescription instance" field with // a new "instance", which is almost the same as the "instance" in // the global plan except the field. // NOTE: The field needs to be changed accordingly. CORBA::ULong index_ins = child_plan->instance.length (); child_plan->instance.length (++index_ins); child_plan->instance[index_ins-1] = my_instance; // Change the field of the "instance". // @@ The implementationRef starts from 0. // @@TODO: Below logic needs to be changed once we want to avoid // duplicate for the optimization. child_plan->instance[index_ins-1].implementationRef = index_ins-1; } return 1; } void CIAO::DomainApplicationManager_Impl:: add_connections (const Deployment::Connections & incoming_conn) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::add_connections"); CORBA::ULong const old_len = this->all_connections_->length (); // Expand the length of the sequence. this->all_connections_->length (old_len + incoming_conn.length ()); // Store the connections to the sequence const CORBA::ULong conn_lenth = incoming_conn.length (); for (CORBA::ULong i = 0; i < conn_lenth; ++i) { (*this->all_connections_)[old_len + i] = incoming_conn[i]; } } void CIAO::DomainApplicationManager_Impl:: startLaunch (const ::Deployment::Properties & configProperty, ::CORBA::Boolean start ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, ::Deployment::ResourceNotAvailable, ::Deployment::StartError, ::Deployment::InvalidProperty)) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::startLaunch"); ACE_UNUSED_ARG (start); ACE_TRY { // Clean up all cached connections first this->all_connections_->length (0); // Invoke startLaunch() operations on each cached NodeApplicationManager for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) { // Get the NodeApplicationManager object reference. ACE_Hash_Map_Entry *entry = 0; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::startLaunch -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("Unable to resolve a reference to node manager: "); error += this->node_manager_names_[i]; ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl:startLaunch", error.c_str ())); } ::Deployment::NodeApplicationManager_ptr my_nam = (entry->int_id_).node_application_manager_.in (); if (CORBA::is_nil (my_nam)) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::startLaunch -" "ERROR while narrowing the NAM " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("While starting launch, the DomainApplicationManager\ has a nil reference for NodeApplicationManager\n"); ACE_DEBUG ((LM_DEBUG, error.c_str ())); ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl::startLaunch", error.c_str ())); } ACE_TRY_CHECK; ::Deployment::Connections_var retn_connections; // Obtained the returned NodeApplication object reference // and the returned Connections variable. ::Deployment::Application_var temp_application; if (!is_redeployment_) { temp_application = my_nam->startLaunch (configProperty, retn_connections.out (), 0); } else { //============================================================= // Add New Components Logic //============================================================= // Let's add new components only now, the to-be-removed // components should be removed AFTER the connections // are removed. temp_application = my_nam->perform_redeployment (configProperty, retn_connections.out (), true, // add new components only now 0); } // Narrow down to NodeApplication object reference ::Deployment::NodeApplication_var my_na = ::Deployment::NodeApplication::_narrow (temp_application.in () ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; if (CORBA::is_nil (my_na.in ())) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::startLaunch -" "ERROR while narrowing the NAM " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("The DomainApplicationManager receives a nil " "reference of NodeApplication after calling " "startLaunch on NodeApplicationManager.\n"); ACE_ERROR ((LM_ERROR, error.c_str ())); ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl::startLaunch", error.c_str ())); } ACE_TRY_CHECK; // Cache the returned set of connections into the list. this->add_connections (retn_connections.in ()); // Cache the returned NodeApplication object reference into // the hash table. (entry->int_id_).node_application_ = my_na._retn (); } this->synchronize_shared_components_with_node_managers (); } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::startLaunch\t\n"); ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } void CIAO::DomainApplicationManager_Impl:: install_all_es (void) ACE_THROW_SPEC ((CORBA::SystemException, Deployment::StartError)) { ACE_TRY { for (CORBA::ULong j = 0; j < this->esd_->length (); ++j) { // Construct the ESInstallationInfos data Deployment::ESInstallationInfos_var es_infos; ACE_NEW (es_infos, Deployment::ESInstallationInfos); es_infos->length (1); (*es_infos)[0].id = this->esd_[j].name.in (); (*es_infos)[0].type = CIAO::RTEC; //only RTEC is supported so far (*es_infos)[0].svcconf = this->esd_[j].svc_cfg_file.in (); // Find NA, and then invoke operation on it ACE_Hash_Map_Entry *entry = 0; if (this->artifact_map_.find (this->esd_[j].node.in (), entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::install_all_es -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->esd_[j].node.in ())); ACE_CString error ("Unable to resolve a reference to NodeManager: "); error += this->esd_[j].node.in (); ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl::install_all_es", error.c_str ())); } // Invoke install_es () operation on each cached NodeApplication object. ::Deployment::NodeApplication_ptr my_na = (entry->int_id_).node_application_.in (); ::Deployment::CIAO_Event_Services_var event_services = my_na->install_es (es_infos); // Add these returned ES objects into the cached map this->add_es_to_map (es_infos, event_services); } } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::post_finishLaunch.\n"); ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } void CIAO::DomainApplicationManager_Impl:: add_es_to_map (Deployment::ESInstallationInfos * es_infos, Deployment::CIAO_Event_Services * event_services) ACE_THROW_SPEC ((CORBA::SystemException, Deployment::StartError)) { ACE_TRY { CORBA::ULong es_length = event_services->length (); for (CORBA::ULong i = 0; i < es_length; ++i) { this->es_map_.bind ( (*es_infos)[i].id.in (), CIAO::CIAO_Event_Service::_duplicate ((*event_services)[i])); } } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::add_es_to_map.\n"); ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } void CIAO::DomainApplicationManager_Impl:: finishLaunch (CORBA::Boolean start, CORBA::Boolean is_ReDaC ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, Deployment::StartError)) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::finishLaunch"); ACE_TRY { // Install all the CIAO_Event_Services within the Deployment Plan this->install_all_es (); // Invoke finishLaunch() operation on each cached NodeApplication object. // This will establish bindings for only those internal components, but // NOT for those external/shared components, which requires special // handling, since these components are outside the control of this // DomainApplicationManager. for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) { // Get the NodeApplication object reference. ACE_Hash_Map_Entry * entry; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::finishLaunch -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("Unable to resolve a reference to NodeManager: "); error += this->node_manager_names_[i]; ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl::finishLaunch", error.c_str ())); } //@@ Note: Don't delete the below debugging helpers. // Dump the connections for debug purpose. if (CIAO::debug_level () > 9) { ACE_DEBUG ((LM_DEBUG, "==============================================\n")); ACE_DEBUG ((LM_DEBUG, "dump incoming connections for child plan:%s\n", (entry->int_id_).child_plan_->UUID.in ())); dump_connections (this->all_connections_.in ()); ACE_DEBUG ((LM_DEBUG, "==============================================\n")); } // Get the Connections variable, if ReDaC is true, then we get // those new connections only. NOTE: get_outgoing_connections // by default will get *all* connections. Deployment::Connections * my_connections = this->get_outgoing_connections ( (entry->int_id_).child_plan_.in (), !is_ReDaC, true, // we search *new* plan DomainApplicationManager_Impl::Internal_Connections ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; if (my_connections == 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::finishLaunch -" "ERROR while getting the outgoing connections " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl::finish_launch", "There was some error establishing connections.")); } // Dump the connections for debug purpose. if (CIAO::debug_level () > 1) { ACE_DEBUG ((LM_DEBUG, "==============================================\n")); ACE_DEBUG ((LM_DEBUG, "dump outgoing connections for child plan:%s\n", (entry->int_id_).child_plan_->UUID.in ())); dump_connections (*my_connections); ACE_DEBUG ((LM_DEBUG, "==============================================\n")); } // Invoke finishLaunch() operation on NodeApplication. if (my_connections->length () != 0) { entry->int_id_.node_application_->finishLaunch (*my_connections, start, true // "true" => establish new connections only ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } //============================================================= // Remove Old Connections Logic //============================================================= if (is_ReDaC) // We should also *REMOVE* unnecessary connections { // If this is a brand new child plan, then continue. if ((entry->int_id_).old_child_plan_ == 0) continue; // Get all the connections in the old deployment plan Deployment::Connections * connections_in_old_plan = this->get_outgoing_connections ( (entry->int_id_).old_child_plan_.in (), true, // yes, get *all* the connections false, // search in the *old* plan DomainApplicationManager_Impl::Internal_Connections ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; // Pass in the "false" parameter to get *all* the connections in // the new deployment plan, regardless those in old plan Deployment::Connections * connections_in_new_plan = this->get_outgoing_connections ( (entry->int_id_).child_plan_.in (), true, // yes, get *all* the connections true, // search in the *new* plan DomainApplicationManager_Impl::Internal_Connections ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; Deployment::Connections * unnecessary_connections = this->subtract_connections (*connections_in_old_plan, *connections_in_new_plan); delete connections_in_old_plan; delete connections_in_new_plan; // Dump the connections for debug purpose. if (CIAO::debug_level () > 1) { ACE_DEBUG ((LM_DEBUG, "==============================================\n")); ACE_DEBUG ((LM_DEBUG, "dump to-be-removed connections for child plan:%s\n", (entry->int_id_).child_plan_->UUID.in ())); dump_connections (*unnecessary_connections); ACE_DEBUG ((LM_DEBUG, "==============================================\n")); } // Invoke finishLaunch() operation on NodeApplication. if (unnecessary_connections->length () != 0) { ACE_ASSERT (!CORBA::is_nil (entry->int_id_.node_application_.in ())); entry->int_id_.node_application_->finishLaunch (*unnecessary_connections, start, false // false ==> remove unnecessary connections ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } //============================================================= // Remove Old Components //============================================================= // Finally we need to remove those to-be-removed components ::Deployment::Properties_var configProperty; ACE_NEW (configProperty, Deployment::Properties); ::Deployment::Connections_var retn_connections; Deployment::Application_var temp_application = entry->int_id_.node_application_manager_-> perform_redeployment (configProperty, retn_connections.out (), false, // remove old components only false);// do not "start" } } // Establish bindings on external/shared components of this deployment plan. this->post_finishLaunch (); } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::finishLaunch: " "Killing NodeApplications.\n"); // Invoke destroyManager() operation on each cached // NodeManager object. for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) { // Get the NodeManager and NodeApplicationManager object references. ACE_Hash_Map_Entry * entry = 0; this->artifact_map_.find (this->node_manager_names_[i],entry); ::Deployment::NodeApplicationManager_ptr my_node_application_manager = (entry->int_id_).node_application_manager_.in (); // Invoke destoryApplication() operation on the NodeApplicationManger. // Since we have the first arg is not used by NAM anyway. my_node_application_manager->destroyApplication (0 ACE_ENV_ARG_PARAMETER); ACE_CHECK; } ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } void CIAO::DomainApplicationManager_Impl:: post_finishLaunch (void) ACE_THROW_SPEC ((CORBA::SystemException, Deployment::StartError)) { ACE_TRY { // For each "external" component... CORBA::ULong length = this->shared_->length (); for (CORBA::ULong j = 0; j < length; ++j) { // Construct struct for the component CIAO::Component_Binding_Info * binding = this->populate_binding_info ( this->shared_[j].name.in (), this->shared_[j].plan_uuid.in ()); // Invoke on ExecutionManager this->execution_manager_->finalize_global_binding ( *binding, true); delete binding; } } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::post_finishLaunch.\n"); ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } CIAO::Component_Binding_Info * CIAO::DomainApplicationManager_Impl:: populate_binding_info (const ACE_CString& name, const ACE_CString& child_uuid) { CIAO::Component_Binding_Info * retv; ACE_NEW_RETURN (retv, CIAO::Component_Binding_Info (), 0); retv->name_ = name; // Parse the child_uuid string and populate the "node" name and "plan_uuid" fields. // Our protocol here is searching for the "@", the substring *before* that is the // global plan uuid, and the substring *after* that is the node name. size_t pos = child_uuid.find ('@'); retv->plan_uuid_ = child_uuid.substring (0, pos); retv->node_ = child_uuid.substring (pos+1, -1); // get the rest of the string Deployment::Connections_var connections; ACE_NEW_RETURN (connections, Deployment::Connections, 0); this->get_outgoing_connections_i (name.c_str (), connections.inout (), false, // get *all* connections true); // search current plan retv->providedReference_ = connections._retn (); return retv; } CIAO::Component_Binding_Info * CIAO::DomainApplicationManager_Impl:: populate_binding_info (const ACE_CString& name) { CIAO::Component_Binding_Info * retv; ACE_NEW_RETURN (retv, CIAO::Component_Binding_Info (), 0); // Looking for the child plan uuid through the shared compoonent list for (CORBA::ULong i = 0; i < this->shared_->length (); ++i) { if (ACE_OS::strcmp (this->shared_[i].name.in (), name.c_str ()) == 0) { ACE_CString child_uuid = this->shared_[i].plan_uuid.in (); retv = this->populate_binding_info (name, child_uuid); return retv; } } return 0; // If no matching is found (should never happen). } void CIAO::DomainApplicationManager_Impl:: add_shared_components (const Deployment::ComponentPlans & shared) { for (CORBA::ULong i = 0; i < shared.length (); ++i) { CORBA::ULong curr_len = this->shared_->length (); this->shared_->length (curr_len + 1); this->shared_[curr_len] = shared[i]; } } bool CIAO::DomainApplicationManager_Impl:: is_shared_component (const char * name) { for (CORBA::ULong i = 0; i < this->shared_->length (); ++i) { if (ACE_OS::strcmp (this->shared_[i].name.in (), name) == 0) return true; } return false; } void CIAO::DomainApplicationManager_Impl:: synchronize_shared_components_with_node_managers (void) { for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) { // Get the NodeManager object reference. ACE_Hash_Map_Entry *entry = 0; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::startLaunch -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("Unable to resolve a reference to node manager: "); error += this->node_manager_names_[i]; ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl:startLaunch", error.c_str ())); } // Update the shared components list ::Deployment::NodeManager_ptr my_node_manager = (entry->int_id_).node_manager_.in (); Deployment::ComponentPlans_var shared = my_node_manager->get_shared_components (); this->add_shared_components (shared.in ()); } } Deployment::Connections * CIAO::DomainApplicationManager_Impl:: get_outgoing_connections (const Deployment::DeploymentPlan &plan, bool is_getting_all_connections, bool is_search_new_plan, Connection_Search_Type t ACE_ENV_ARG_DECL) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::get_outgoing_connections"); Deployment::Connections_var connections; ACE_NEW_RETURN (connections, Deployment::Connections, 0); // For each component instance in the child plan ... CORBA::ULong number = plan.instance.length (); for (CORBA::ULong i = 0; i < number; ++i) { if (t == Internal_Connections && this->is_shared_component (plan.instance[i].name.in ())) continue; // Get the outgoing connections of the component if (!get_outgoing_connections_i (plan.instance[i].name.in (), connections.inout (), is_getting_all_connections, is_search_new_plan ACE_ENV_ARG_PARAMETER)) return 0; } return connections._retn (); } // Get outgoing connections for particular instance bool CIAO::DomainApplicationManager_Impl:: get_outgoing_connections_i (const char * instname, Deployment::Connections & retv, bool is_getting_all_connections, bool is_search_new_plan ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((Deployment::StartError)) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::get_outoing_connections_i"); Deployment::DeploymentPlan tmp_plan; if (is_search_new_plan) tmp_plan = this->plan_; else tmp_plan = this->old_plan_; // Search for all the bindings in the plan. const CORBA::ULong total_length = tmp_plan.connection.length(); for (CORBA::ULong i = 0; i < total_length; ++i) { // Current binding that we are looking at. const Deployment::PlanConnectionDescription & binding = tmp_plan.connection[i]; // If this is a ReDaC case, then we ignore the connection if it // already exists in the old_plan if (already_exists (binding) && !is_getting_all_connections) continue; this->populate_connection_for_binding (instname, binding, tmp_plan, retv); } return true; } // Search the current binding to see whether a connection of this // component needs to be populated bool CIAO::DomainApplicationManager_Impl:: populate_connection_for_binding ( const char * instname, const Deployment::PlanConnectionDescription & binding, const Deployment::DeploymentPlan & plan, Deployment::Connections & retv) ACE_THROW_SPEC ((Deployment::StartError)) { const CORBA::ULong binding_len = binding.internalEndpoint.length (); if (binding_len == 1) { switch (binding.internalEndpoint[0].kind) { case Deployment::rtecEventPublisher: case Deployment::rtecEventConsumer: return this->handle_es_connection (instname, binding, plan, retv); default: ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::" "populate_connection_for_binding -" "invalid connection specified in deployment plan\n")); return false; } } else if (binding_len == 2) { return this->handle_direct_connection (instname, binding, plan, retv); } else // invalid binding encounted... return false; } bool CIAO::DomainApplicationManager_Impl:: handle_es_connection ( const char * instname, const Deployment::PlanConnectionDescription & binding, const Deployment::DeploymentPlan & plan, Deployment::Connections & retv) ACE_THROW_SPEC ((Deployment::StartError)) { // The initial retv might have something inside CORBA::ULong len = retv.length (); const Deployment::PlanSubcomponentPortEndpoint & endpoint = binding.internalEndpoint[0]; // If the instance name does NOT match one of the names in the binding // Then thsi binding has nothing related to myself (an instance) if (ACE_OS::strcmp (instname, plan.instance[endpoint.instanceRef].name.in ()) != 0) return false; if (binding.externalReference.length () != 1) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::" "handle_publisher_es_connection -" "externalReference must have length of 1.\n")); return false; } retv.length (len+1); retv[len].instanceName = instname; retv[len].portName = endpoint.portName.in (); retv[len].kind = endpoint.kind; ACE_CString es_id = binding.externalReference[0].location.in (); retv[len].endpointInstanceName = es_id.c_str (); retv[len].endpointPortName = "CIAO_ES"; // We need to populate the actual filter and store it into // the field if (binding.deployRequirement.length () != 0) { retv[len].config = this->get_connection_QoS_configuration (binding.deployRequirement[0]); } // If we didnt find the objref of the connection ... CIAO::CIAO_Event_Service_var es; if (this->es_map_.find (es_id.c_str (), es) != 0) { ACE_CString error ("Creating connections for "); error += instname; error += ": unable to find object reference for connection "; error += binding.name.in (); ACE_THROW_RETURN (Deployment::StartError ("DomainApplicationManager_Impl::create_connections_i", error.c_str ()), false); } retv[len].event_service = es._retn (); // One more thing needs to be done if this is a es_consumer connection if (endpoint.kind == Deployment::rtecEventConsumer) { // Now we search in the received connections to get the objRef of event sink bool found = false; const CORBA::ULong all_conn_len = this->all_connections_->length (); for (CORBA::ULong j = 0; j < all_conn_len; ++j) { const Deployment::Connection & curr_recv_conn = this->all_connections_[j]; // We need to look at the instance name and the port name to confirm. if (ACE_OS::strcmp (curr_recv_conn.instanceName.in (), instname) == 0 && ACE_OS::strcmp (curr_recv_conn.portName.in (), endpoint.portName.in ()) == 0) { retv[len].endpoint = CORBA::Object::_duplicate(curr_recv_conn.endpoint.in ()); found = true; } } // End of searching received connections if (!found) { ACE_CString error ("Creating connections for "); error += instname; error += ": unable to find object reference for connection "; error += binding.name.in (); ACE_THROW_RETURN (Deployment::StartError ("DomainApplicationManager_Impl::handle_es_connection", error.c_str ()), false); } } return true; } bool CIAO::DomainApplicationManager_Impl:: handle_direct_connection ( const char * instname, const Deployment::PlanConnectionDescription & binding, const Deployment::DeploymentPlan & plan, Deployment::Connections & retv) ACE_THROW_SPEC ((Deployment::StartError)) { // The initial retv might have something inside CORBA::ULong len = retv.length (); const CORBA::ULong binding_len = binding.internalEndpoint.length (); for (CORBA::ULong i = 0; i < binding_len; ++i) { const Deployment::PlanSubcomponentPortEndpoint & endpoint = binding.internalEndpoint[i]; // If the instance name does NOT match one of the names in the binding if (ACE_OS::strcmp (instname, plan.instance[endpoint.instanceRef].name.in ()) != 0) continue; // We are only interested when we are the "client" of the endpoint objref if (endpoint.kind == Deployment::EventPublisher || endpoint.kind == Deployment::EventEmitter || endpoint.kind == Deployment::SimplexReceptacle || endpoint.kind == Deployment::MultiplexReceptacle ) { // Obtain the index of the "real" endpoint which has an objref. It // is the opposite side of myself. CORBA::ULong e_index = (i + 1) % 2; ACE_CString source_port = binding.internalEndpoint[i].portName.in (); ACE_CString endpoint_inst = plan.instance[binding.internalEndpoint[e_index] .instanceRef].name.in (); ACE_CString endpoint_port = binding.internalEndpoint[e_index].portName.in (); bool found = false; // Now we search in the received connections to get the objRef. const CORBA::ULong all_conn_len = this->all_connections_->length (); for (CORBA::ULong j = 0; j < all_conn_len; ++j) { const Deployment::Connection & curr_recv_conn = this->all_connections_[j]; // We need to look at the instance name and the port name to confirm. if (ACE_OS::strcmp (curr_recv_conn.instanceName.in (), endpoint_inst.c_str ()) == 0 && ACE_OS::strcmp (curr_recv_conn.portName.in (), endpoint_port.c_str ()) == 0) { retv.length (len+1); retv[len].instanceName = instname; retv[len].portName = source_port.c_str (); retv[len].endpointInstanceName = endpoint_inst.c_str (); retv[len].endpointPortName = endpoint_port.c_str (); retv[len].endpoint = CORBA::Object::_duplicate(curr_recv_conn.endpoint.in ()); retv[len].kind = binding.internalEndpoint[i].kind; ++len; found = true; break; } } // End of searching received connections // We didnt find the objref of the connection ... if (!found) { ACE_CString error ("Creating connections for "); error += instname; error += ": unable to find object reference for connection "; error += binding.name.in (); ACE_THROW_RETURN (Deployment::StartError ("DomainApplicationManager_Impl::create_connections_i", error.c_str ()), false); } break; } } return true; } void CIAO::DomainApplicationManager_Impl:: start (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, ::Deployment::StartError)) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::start"); ACE_TRY { CORBA::ULong i; for (i = 0; i < this->num_child_plans_; ++i) { // Get the NodeApplication object reference. ACE_Hash_Map_Entry *entry; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::start -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("Unable to resolve a reference to node manager: "); error += this->node_manager_names_[i]; ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl:startLaunch", error.c_str ())); } ::Deployment::NodeApplication_ptr my_na = (entry->int_id_).node_application_.in (); my_na->ciao_preactivate (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; } // Invoke start () operation on each cached NodeApplication object. for (i = 0; i < this->num_child_plans_; ++i) { // Get the NodeApplication object reference. ACE_Hash_Map_Entry *entry; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::start -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_TRY_THROW (Deployment::StartError ()); } ::Deployment::NodeApplication_ptr my_na = (entry->int_id_).node_application_.in (); my_na->start (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; } // Invoke ciao_postctivate () operation on each // cached NodeApplication object. for (i = 0; i < this->num_child_plans_; ++i) { // Get the NodeApplication object reference. ACE_Hash_Map_Entry *entry; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::start -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("Unable to resolve a reference to node manager: "); error += this->node_manager_names_[i]; ACE_TRY_THROW (Deployment::StartError ("DomainApplicationManager_Impl:startLaunch", error.c_str ())); } ::Deployment::NodeApplication_ptr my_na = (entry->int_id_).node_application_.in (); my_na->ciao_postactivate (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; } } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::start\t\n"); ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } void CIAO::DomainApplicationManager_Impl:: destroyApplication (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, ::Deployment::StopError)) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::destroyApplication"); ACE_TRY { for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) { ACE_Hash_Map_Entry *entry = 0; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) { ACE_ERROR ((LM_ERROR, "DAnCE (%P|%t) DomainApplicationManager_Impl.cpp -" "CIAO::DomainApplicationManager_Impl::destroyApplication -" "ERROR while finding the node specific plan " "for the node [%s] \n", this->node_manager_names_[i].c_str ())); ACE_CString error ("Unable to resolve a reference to NodeManager: "); error += this->node_manager_names_[i]; ACE_TRY_THROW (Deployment::StopError ("DomainApplicationManager_Impl::destroyApplication", error.c_str ())); } // Invoke ciao_passivate () operation on each cached NodeApplication object. ::Deployment::NodeApplication_ptr my_na = (entry->int_id_).node_application_.in (); my_na->ciao_passivate (); Deployment::Connections_var connections = this->get_outgoing_connections ( (entry->int_id_).child_plan_.in (), true, // yes, get *all* the connections true, // yes, we search the current plan DomainApplicationManager_Impl::External_Connections ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; // Invoke finishLaunch() on NodeApplication to remove bindings. // If this NodeApplication is not within the control of this DAM, // then we should delegate the call to the correct DAM through EM. // Iterave over the returned connection list in , // (1) If this is a shared component, then we remove this connection // from list, and then populate a "Component_Binding_Info" // struct for it and send to EM for remove. // (2) For the rest of the connections, we send them to the NAs // managed by the local DAM to remove. for (CORBA::ULong j = 0; j < connections->length (); ++j) { if (this->is_shared_component (connections[j].instanceName.in ())) { // ask EM to remove the binding for us CIAO::Component_Binding_Info * binding = this->populate_binding_info ( connections[j].instanceName.in ()); this->execution_manager_->finalize_global_binding ( *binding, false); // If this element is the last one in the sequence if (j == connections->length () - 1) { connections->length (connections->length () - 1); break; } // otherwise, remove this element from the list for (CORBA::ULong k = j; k < connections->length (); ++k) { connections[k] = connections [k + 1]; connections->length (connections->length () - 1); } } } entry->int_id_.node_application_->finishLaunch (connections.in (), true, // "true" ==> argument not used anymore false // "false" => remove connections ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } // After all the connections are removed, we actually destroy for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) { ACE_Hash_Map_Entry *entry = 0; this->artifact_map_.find (this->node_manager_names_[i], entry); // Invoke destroyPlan() operation on the NodeManager Deployment::NodeManager_var my_node_manager = (entry->int_id_).node_manager_; my_node_manager->destroyPlan ((entry->int_id_).child_plan_ ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } // ?? // Shall we invoke destroyManager () operation on the NodeManager, since we need // to clean up all the NodeApplicationManagers associated with this deployment // plan (one NodeApplicationManager per Node per plan). } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::destroyApplication\t\n"); ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } void CIAO::DomainApplicationManager_Impl:: destroyManager (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, Deployment::StopError)) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::destroyManager"); ACE_TRY { for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) { // Get the NodeManager and NodeApplicationManager object references. ACE_Hash_Map_Entry *entry = 0; if (this->artifact_map_.find (this->node_manager_names_[i], entry) != 0) ACE_TRY_THROW (Deployment::StopError ()); // Should never happen! ::Deployment::NodeManager_var my_node_manager = (entry->int_id_).node_manager_; ::Deployment::NodeApplicationManager_var my_nam = (entry->int_id_).node_application_manager_; my_node_manager->destroyManager (my_nam.in () ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::destroyManager\t\n"); ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } void CIAO::DomainApplicationManager_Impl:: perform_redeployment ( const Deployment::DeploymentPlan & plan ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, Deployment::PlanError, Deployment::InstallationFailure, Deployment::UnknownImplId, Deployment::ImplEntryPointNotFound, Deployment::InvalidConnection, ::Components::RemoveFailure)) { // Currently we could dynamically update the NodeManagerMap topology, // but later maybe we could add another parameter to this operation, // which allows the user to specify the new NodeManagerMap data file. this->old_plan_ = this->plan_; this->is_redeployment_ = true; this->plan_ = plan; ACE_TRY { // Call init() on the myself, which will validate/split the plan and // call preparePlan on each NodeManager, by this, we shall get // all the object references of NM and NAM associated with each // component instance populated. this->init (); // Call startLaunch on each NM for each child plan, this should not only // install all the new components specified, but should also remove // the components that are no longer in the new deployment plan. // Meanwhile, we should set up the container configurations appropriately, // whose information is fully captured in the node-level deployment plan. ::Deployment::Properties_var properties; ACE_NEW (properties, Deployment::Properties); this->startLaunch (properties.in (), false); // finishLaunch will (1) establish new connections, and (2) // get rid of those non-existing connections. As we know, in the // node level, the connections are cached within the NodeApplication *and* // Container, then we should modify the implementation of the // on the NodeApplication to accomplish this. this->finishLaunch (true, true); // true means start activation also. // ture means "ReDaC" is desired this->start (); } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "DomainApplicationManager_Impl::perform_redeployment\t\n"); this->plan_ = this->old_plan_; ACE_RE_THROW; } ACE_ENDTRY; ACE_CHECK; } // Returns the DeploymentPlan associated with this ApplicationManager. ::Deployment::DeploymentPlan * CIAO::DomainApplicationManager_Impl:: getPlan (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException)) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::getPlan"); Deployment::DeploymentPlan_var plan = 0; // Make a deep copy of the Plan ACE_NEW_THROW_EX (plan, Deployment::DeploymentPlan (this->plan_), CORBA::NO_MEMORY ()); // Transfer ownership return plan._retn (); } void CIAO::DomainApplicationManager_Impl:: dump_connections (const ::Deployment::Connections & connections) { CIAO_TRACE("CIAO::DomainApplicationManager_Impl::dump_connections"); const CORBA::ULong conn_len = connections.length (); for (CORBA::ULong i = 0; i < conn_len; ++i) { ACE_DEBUG ((LM_DEBUG, "instanceName: %s\n", connections[i].instanceName.in ())); ACE_DEBUG ((LM_DEBUG, "portName: %s\n", connections[i].portName.in ())); ACE_DEBUG ((LM_DEBUG, "portkind: ")); switch (connections[i].kind) { case Deployment::Facet: ACE_DEBUG ((LM_DEBUG, "Facet\n")); break; case Deployment::SimplexReceptacle: ACE_DEBUG ((LM_DEBUG, "SimplexReceptacle\n")); break; case Deployment::MultiplexReceptacle: ACE_DEBUG ((LM_DEBUG, "MultiplexReceptacle\n")); break; case Deployment::EventEmitter: ACE_DEBUG ((LM_DEBUG, "EventEmitter\n")); break; case Deployment::EventPublisher: ACE_DEBUG ((LM_DEBUG, "EventPublisher\n")); break; case Deployment::EventConsumer: ACE_DEBUG ((LM_DEBUG, "EventConsumer\n")); break; case Deployment::rtecEventPublisher: ACE_DEBUG ((LM_DEBUG, "rtecEventPublisher\n")); break; case Deployment::rtecEventConsumer: ACE_DEBUG ((LM_DEBUG, "rtecEventConsumer\n")); break; default: ACE_DEBUG ((LM_DEBUG, "Unknown port kind.\n")); } ACE_DEBUG ((LM_DEBUG, "endpointInstanceName: %s\n", connections[i].endpointInstanceName.in ())); ACE_DEBUG ((LM_DEBUG, "endpointPortName: %s\n", connections[i].endpointPortName.in ())); ACE_DEBUG ((LM_DEBUG, "---------------------\n")); } } bool CIAO::DomainApplicationManager_Impl:: already_exists (const Deployment::PlanConnectionDescription & conn) { const CORBA::ULong conn_len = this->old_plan_.connection.length(); for(CORBA::ULong i = 0; i < conn_len; ++i) { if (ACE_OS::strcmp (this->old_plan_.connection[i].name.in (), conn.name.in ()) == 0) return true; } return false; } Deployment::Connections * CIAO::DomainApplicationManager_Impl:: subtract_connections (const Deployment::Connections & left, const Deployment::Connections & right) { Deployment::Connections_var retv; ACE_NEW_RETURN (retv, Deployment::Connections, 0); CORBA::ULong left_length = left.length (); CORBA::ULong right_length = right.length (); for (CORBA::ULong i = 0; i < left_length; ++i) { bool found = false; for (CORBA::ULong j = 0; j < right_length; ++j) { if (ACE_OS::strcmp (left[i].instanceName.in (), right[j].instanceName.in ()) == 0 && ACE_OS::strcmp (left[i].portName.in (), right[j].portName.in ()) == 0 && left[i].kind == right[j].kind && left[i].endpoint->_is_equivalent (right[j].endpoint.in ())) { found = true; break; } } if (!found) { CORBA::ULong curr_length = retv->length (); retv->length (curr_length + 1); retv[curr_length] = left[i]; } } return retv._retn (); } const Deployment::Properties & CIAO::DomainApplicationManager_Impl:: get_connection_QoS_configuration (const Deployment::Requirement & requirement) { // Get the name/identifier of the filter associated with // this connection Deployment::Properties_var retv; ACE_NEW_NORETURN (retv, Deployment::Properties); CORBA::ULong len = retv->length (); for (CORBA::ULong i = 0; i < requirement.property.length (); ++i) { const char *filter_name; if (ACE_OS::strcmp ("EventFilter", requirement.property[i].name) == 0) { if ((requirement.property[i].value >>= filter_name) == false) ACE_ERROR ((LM_ERROR, "ERROR: DomainApplicationManager_Impl::" "get_connection_QoS_configuration unable to " "extract event filter information\n")); } // Search for the desired filter for (CORBA::ULong j = 0; j < this->esd_->length (); ++j) { // Populate the "filters" info, in case this CIAO_Event_Service has // one or more filters specified through descriptors for (CORBA::ULong k = 0; k < this->esd_[j].filters.length (); ++k) { if (ACE_OS::strcmp (this->esd_[j].filters[k].name.in (), filter_name) == 0) { retv->length (len + 1); retv[len].name = CORBA::string_dup ("EventFilter"); retv[len].value <<= this->esd_[j].filters[k]; break; } } } } return retv.inout (); }