diff options
Diffstat (limited to 'modules/CIAO/DAnCE')
146 files changed, 24338 insertions, 0 deletions
diff --git a/modules/CIAO/DAnCE/Deployment.mwc b/modules/CIAO/DAnCE/Deployment.mwc new file mode 100644 index 00000000000..fcf95d10967 --- /dev/null +++ b/modules/CIAO/DAnCE/Deployment.mwc @@ -0,0 +1,4 @@ +// $Id$ + +workspace { +} diff --git a/modules/CIAO/DAnCE/DomainApplicationManager/Deployment_Configuration.cpp b/modules/CIAO/DAnCE/DomainApplicationManager/Deployment_Configuration.cpp new file mode 100644 index 00000000000..83775494498 --- /dev/null +++ b/modules/CIAO/DAnCE/DomainApplicationManager/Deployment_Configuration.cpp @@ -0,0 +1,169 @@ +// $Id$ + +#include "Deployment_Configuration.h" +#include "ciao/CIAO_common.h" + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/Read_Buffer.h" + +CIAO::Deployment_Configuration::Deployment_Configuration (CORBA::ORB_ptr o) + : orb_ (CORBA::ORB::_duplicate (o)) +{ +} + +CIAO::Deployment_Configuration::~Deployment_Configuration (void) +{ + this->deployment_info_.unbind_all (); +} + +int +CIAO::Deployment_Configuration::init (const char *filename) +{ + if (filename == 0) + { + ACE_ERROR ((LM_ERROR, "DANCE (%P|%t) Deployment_Configuration.cpp" + ": Unable to identify the file name \n")); + return -1; + } + + FILE *inf = ACE_OS::fopen (filename, "r"); + + if (inf == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "DAnCE (%P|%t) Deployment_Configuration.cpp:" + "Fail to open node manager map data file: <%s>\n", + filename), + -1); + } + + // Get a read buffer, this will close the stream when we are ready + ACE_Read_Buffer reader (inf, true); + + bool first = true; + char* string = 0; + + // Read from the file line by line + while ((string = reader.read ('\n')) != 0) + { + // Search from the right to the first space + const char* ior_start = ACE_OS::strrchr (string, ' '); + // Search from the left to the first space + const char* dest_end = ACE_OS::strchr (string, ' '); + // The destination is first followed by some spaces + ACE_CString destination (string, dest_end - string); + // And then the IOR + ACE_CString ior (ior_start + 1, ACE_OS::strlen (ior_start + 1)); + if (this->deployment_info_.bind (destination.c_str (), ior.c_str ()) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "DAnCE (%P|%t) Deployment_Configuration, " + "failed to bind destination <%s>\n", + destination.c_str ()), + -1); + } + + if (CIAO::debug_level () > 5) + { + ACE_DEBUG ((LM_DEBUG, + "DAnCE (%P|%t) Deployment_Configuration, " + "read <%s> <%s>\n", destination.c_str (), ior.c_str ())); + } + + if (first) + { + this->default_node_manager_.IOR_ = ior; + first = false; + } + } + + return 0; +} + +const char * +CIAO::Deployment_Configuration::get_node_manager_ior (const char *name) const +{ + if (name == 0) + return this->get_default_node_manager_ior (); + + ACE_Hash_Map_Entry + <ACE_CString, + CIAO::Deployment_Configuration::Node_Manager_Info> *entry = 0; + + if (this->deployment_info_.find (ACE_CString (name), + entry) != 0) + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) Deployment_Configuration, " + "get_node_manager_ior, failed to find IOR for destination <%s>\n", + name)); + return 0; + } + + return entry->int_id_.IOR_.c_str (); +} + +const char * +CIAO::Deployment_Configuration::get_default_node_manager_ior (void) const +{ + if (this->default_node_manager_.IOR_.length () == 0) + return 0; + return this->default_node_manager_.IOR_.c_str (); +} + +::Deployment::NodeManager_ptr +CIAO::Deployment_Configuration::get_node_manager (const char *name) +{ + if (name == 0) + return get_default_node_manager (); + + ACE_Hash_Map_Entry + <ACE_CString, + CIAO::Deployment_Configuration::Node_Manager_Info> *entry = 0; + + if (this->deployment_info_.find (ACE_CString (name), + entry) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "DAnCE (%P|%t) Deployment_Configuration.cpp:" + "Failed to find IOR for destination <%s>\n", + name), + 0); + } + + if (CORBA::is_nil (entry->int_id_.node_manager_.in ())) + { + try + { + CORBA::Object_var temp = this->orb_->string_to_object + (entry->int_id_.IOR_.c_str ()); + + entry->int_id_.node_manager_ = + ::Deployment::NodeManager::_narrow (temp.in ()); + } + catch (const CORBA::Exception&) + { + ACE_ERROR ((LM_ERROR, "DANCE (%P|%t) Deployment_Configuration.cpp: " + "Error while contacting NodeManager %s\n", name)); + throw; + } + } + return ::Deployment::NodeManager::_duplicate + (entry->int_id_.node_manager_.in ()); +} + +::Deployment::NodeManager_ptr +CIAO::Deployment_Configuration::get_default_node_manager () +{ + if (CORBA::is_nil (this->default_node_manager_.node_manager_.in ())) + { + CORBA::Object_var temp = this->orb_->string_to_object + (this->default_node_manager_.IOR_.c_str ()); + + this->default_node_manager_.node_manager_ = + ::Deployment::NodeManager::_narrow (temp.in ()); + } + return ::Deployment::NodeManager::_duplicate + (this->default_node_manager_.node_manager_.in ()); +} diff --git a/modules/CIAO/DAnCE/DomainApplicationManager/Deployment_Configuration.h b/modules/CIAO/DAnCE/DomainApplicationManager/Deployment_Configuration.h new file mode 100644 index 00000000000..af17d4357ed --- /dev/null +++ b/modules/CIAO/DAnCE/DomainApplicationManager/Deployment_Configuration.h @@ -0,0 +1,128 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Deployment_Configuration.h + * + * $Id$ + * + * The Deployment_Configuration provides abstraction for the + * deployment mechanisms. + * + * @author Nanbor Wang <nanbor@cs.wustl.edu> + * @author Gan Deng <gan.deng@vanderbilt.edu> + */ +//============================================================================= +#ifndef CIAO_DEPLOYMENT_CONFIGURATION_H +#define CIAO_DEPLOYMENT_CONFIGURATION_H +#include /**/ "ace/pre.h" + +#include "ace/Hash_Map_Manager_T.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ciao/Deployment_NodeManagerC.h" +#include "tao/Valuetype/ValueBase.h" +#include "tao/Valuetype/Valuetype_Adapter_Impl.h" +#include "ace/SString.h" + +#include "DomainApplicationManager/DomainApplicationManager_Export.h" + +namespace CIAO +{ + /** + * @class Deployment_Configuration + * + * @brief A class that provides strategies on deployment topology. + * + * This class provides strategies on how the DomainApplicationManager + * should deploy an deployment plan at domain-level. This is achieved + * by providing mappings from deployment destination names to actually + * NodeManager daemon IORs, and the strategy for which default NodeManager + * daemons a deployment mechanism should use. + * + * This is a trivial implementation of the deployment configuration + * strategy. We can enhance this class later on to provide + * different deployment location strategies, such as naming service. + */ + class DomainApplicationManager_Export Deployment_Configuration + { + public: + typedef struct _node_manager_info + { + _node_manager_info (const char *ior = 0) + { + IOR_ = ior; + } + + ACE_CString IOR_; + ::Deployment::NodeManager_var node_manager_; + } Node_Manager_Info; + + Deployment_Configuration (CORBA::ORB_ptr o); + + /// Destructor + ~Deployment_Configuration (void); + + /** + * Init method takes the filename to a configuration file which + * has a simple line format of name, ior string delimited by a + * space in each line. + * + * name IOR-string + * + * @retval 0 on success. + * @retval -1 otherwise. + */ + int init (const char *filename); + + /** + * @retval 0 if no valid name were found. When @c name = 0, then + * this function behave exactly as get_default_activator_ior. + */ + const char *get_node_manager_ior (const char *name) const; + + /** + * Return the default NodeManager the DomainApplicationManager + * should use to deploy a component. In this implementation, the + * first entry in the deployment configuration data file is always + * the entry for default activator. + * + * @retval 0 if no valid daemon is configured. + */ + const char *get_default_node_manager_ior () const; + + /** + * @retval nil if no valid name were found. + */ + ::Deployment::NodeManager_ptr + get_node_manager (const char *name); + + /** + * Return the reference to the default NodeManager the + * DomainApplicationManager should use to deploy a node-level + * deployment plan.. + * + * @retval nil if no valid daemon is configured. + */ + ::Deployment::NodeManager_ptr + get_default_node_manager (); + + protected: + CORBA::ORB_var orb_; + + ACE_Hash_Map_Manager_Ex<ACE_CString, + Node_Manager_Info, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> deployment_info_; + + Node_Manager_Info default_node_manager_; + }; + +} + +#include /**/ "ace/post.h" +#endif /* CIAO_DEPLOYMENT_CONFIGURATION_H */ diff --git a/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager.mpc b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager.mpc new file mode 100644 index 00000000000..0fa9d1eaafb --- /dev/null +++ b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager.mpc @@ -0,0 +1,21 @@ +// -*- MPC -*- +// $Id$ + +project (DomainApplicationManager): ciao_deployment_svnt, naming { + sharedname = DomainApplicationManager + after += ExecutionManager_stub + + dynamicflags = DOMAINAPPLICATIONMANAGER_BUILD_DLL + + Source_Files { + DomainApplicationManager_Impl.cpp + Deployment_Configuration.cpp + } + + Header_Files { + DomainApplicationManager_Impl.h + Deployment_Configuration.h + DomainApplicationManager_Export.h + } +} + diff --git a/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Export.h b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Export.h new file mode 100644 index 00000000000..31fa9b914b7 --- /dev/null +++ b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Export.h @@ -0,0 +1,58 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl -s DomainApplicationManager +// ------------------------------ +#ifndef DOMAINAPPLICATIONMANAGER_EXPORT_H +#define DOMAINAPPLICATIONMANAGER_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (DOMAINAPPLICATIONMANAGER_HAS_DLL) +# define DOMAINAPPLICATIONMANAGER_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && DOMAINAPPLICATIONMANAGER_HAS_DLL */ + +#if !defined (DOMAINAPPLICATIONMANAGER_HAS_DLL) +# define DOMAINAPPLICATIONMANAGER_HAS_DLL 1 +#endif /* ! DOMAINAPPLICATIONMANAGER_HAS_DLL */ + +#if defined (DOMAINAPPLICATIONMANAGER_HAS_DLL) && (DOMAINAPPLICATIONMANAGER_HAS_DLL == 1) +# if defined (DOMAINAPPLICATIONMANAGER_BUILD_DLL) +# define DomainApplicationManager_Export ACE_Proper_Export_Flag +# define DOMAINAPPLICATIONMANAGER_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define DOMAINAPPLICATIONMANAGER_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* DOMAINAPPLICATIONMANAGER_BUILD_DLL */ +# define DomainApplicationManager_Export ACE_Proper_Import_Flag +# define DOMAINAPPLICATIONMANAGER_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define DOMAINAPPLICATIONMANAGER_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* DOMAINAPPLICATIONMANAGER_BUILD_DLL */ +#else /* DOMAINAPPLICATIONMANAGER_HAS_DLL == 1 */ +# define DomainApplicationManager_Export +# define DOMAINAPPLICATIONMANAGER_SINGLETON_DECLARATION(T) +# define DOMAINAPPLICATIONMANAGER_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* DOMAINAPPLICATIONMANAGER_HAS_DLL == 1 */ + +// Set DOMAINAPPLICATIONMANAGER_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (DOMAINAPPLICATIONMANAGER_NTRACE) +# if (ACE_NTRACE == 1) +# define DOMAINAPPLICATIONMANAGER_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define DOMAINAPPLICATIONMANAGER_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !DOMAINAPPLICATIONMANAGER_NTRACE */ + +#if (DOMAINAPPLICATIONMANAGER_NTRACE == 1) +# define DOMAINAPPLICATIONMANAGER_TRACE(X) +#else /* (DOMAINAPPLICATIONMANAGER_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define DOMAINAPPLICATIONMANAGER_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (DOMAINAPPLICATIONMANAGER_NTRACE == 1) */ + +#endif /* DOMAINAPPLICATIONMANAGER_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.cpp b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.cpp new file mode 100644 index 00000000000..89dd9a3179e --- /dev/null +++ b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.cpp @@ -0,0 +1,2017 @@ +// $Id$ + +#include "DomainApplicationManager_Impl.h" +#include "ExecutionManager/Execution_Manager_Impl.h" +#include "ciao/Deployment_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_NEW_THROW_EX (this->all_connections_, + Deployment::Connections (), + CORBA::NO_MEMORY ()); + + ACE_NEW_THROW_EX (this->shared_, + Deployment::ComponentPlans (), + CORBA::NO_MEMORY ()); + + ACE_NEW_THROW_EX (this->esd_, + CIAO::DAnCE::EventServiceDeploymentDescriptions (), + CORBA::NO_MEMORY ()); + + for (CORBA::ULong i = 0; i < this->plan_.infoProperty.length (); ++i) + { + if (ACE_OS::strcmp (this->plan_.infoProperty[i].name.in (), + "CIAOEvents") != 0) + continue; + + // Note, we should do a sanity check here to make + // sure we didn't pick up the wrong infoProperty!! + 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 <ACE_CString, Chained_Artifacts> *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)); + throw Deployment::NoSuchName (); + } + + return + Deployment::NodeApplication::_duplicate ( + entry->int_id_.node_application_.in ()); +} + +void +CIAO::DomainApplicationManager_Impl::init () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::PlanError)) +{ + 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")); + 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")); + 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 <ACE_CString, Chained_Artifacts> *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 ())); + 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 ()); + + Deployment::NodeApplicationManager_var app_manager = + Deployment::NodeApplicationManager::_narrow + (tmp_app_manager.in ()); + + 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 ())); + throw + (Deployment::StartError ("DomainApplicationManager_Impl:init", + error.c_str ())); + } + + // Cache the NodeApplicationManager object reference. + artifacts.node_application_manager_ = app_manager._retn (); + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("DomainApplicationManager_Impl::init\t\n"); + throw; + } +} + +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 + CORBA::ULong const 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 + <ACE_CString, + Chained_Artifacts> *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 <instance> 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 + <ACE_CString, + Chained_Artifacts> *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 + // <implementationRef> field of <my_instance> entry. NOTE: The + // <artifactRef> 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 + // <artifactRef> sequence of <my_implementation> 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 <artifact> 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 <artifactRef> field of the MonolithicDeploymentDescription + ulong_seq[iter] = index_art-1; + } + + // Change the <artifactRef> 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 <implementationRef> field. + // NOTE: The <implementationRef> 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 <implementationRef> field of the "instance". + // @@ The implementationRef starts from 0. + // @@TODO: Below logic needs to be changed once we want to avoid + // duplicate <implementation> 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 <all_connection_> sequence. + this->all_connections_->length (old_len + incoming_conn.length ()); + + // Store the connections to the <all_conections_> 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_THROW_SPEC ((CORBA::SystemException, + ::Deployment::ResourceNotAvailable, + ::Deployment::StartError, + ::Deployment::InvalidProperty)) +{ + CIAO_TRACE("CIAO::DomainApplicationManager_Impl::startLaunch"); + ACE_UNUSED_ARG (start); + + 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 + <ACE_CString, + Chained_Artifacts> *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]; + + 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 ())); + + throw + (Deployment::StartError + ("DomainApplicationManager_Impl::startLaunch", + error.c_str ())); + } + + + ::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 ()); + + 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 ())); + + throw + (Deployment::StartError + ("DomainApplicationManager_Impl::startLaunch", + error.c_str ())); + } + + // 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 (); + } + catch (const Deployment::StartError& ex) + { + ACE_DEBUG ((LM_DEBUG, "DAM_Impl:StartError: %s, %s\n", + ex.name.in (), + ex.reason.in ())); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::startLaunch\t\n"); + throw; + } + +} + + +void +CIAO::DomainApplicationManager_Impl::install_all_es (void) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + try + { + for (CORBA::ULong j = 0; j < this->esd_->length (); ++j) + { + // Find NA, and then invoke operation on it + ACE_Hash_Map_Entry <ACE_CString, Chained_Artifacts> *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 (); + + 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 (); + + ::CIAO::CIAO_Event_Service_var ciao_es = + my_na->install_es (this->esd_[j]); + + // Add these returned ES objects into the cached map + this->add_es_to_map (this->esd_[j].name.in (), ciao_es.in ()); + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::install_all_es.\n"); + throw; + } + +} + +void +CIAO::DomainApplicationManager_Impl:: +add_es_to_map (const char * node_name, + CIAO::CIAO_Event_Service * ciao_es) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + try + { + this->es_map_.bind ( + node_name, + CIAO::CIAO_Event_Service::_duplicate (ciao_es)); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::add_es_to_map.\n"); + throw; + } + +} + +void +CIAO::DomainApplicationManager_Impl:: +finishLaunch (CORBA::Boolean start, + CORBA::Boolean is_ReDaC) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + CIAO_TRACE("CIAO::DomainApplicationManager_Impl::finishLaunch"); + 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 <ACE_CString, Chained_Artifacts> * 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::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]; + + 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); + + 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 ())); + + 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 + ); + } + + //============================================================= + // 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); + + // 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); + + 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) + { + if (CORBA::is_nil (entry->int_id_.node_application_.in ())) + throw Deployment::StartError (); + + entry->int_id_.node_application_->finishLaunch + (*unnecessary_connections, + start, + false // false ==> remove unnecessary connections + ); + } + + //============================================================= + // 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 (); + } + catch (const Deployment::StartError& ex) + { + ACE_ERROR ((LM_ERROR, "DAM_Impl::finishLaunch - StartError: %s, %s\n", + ex.name.in (), + ex.reason.in ())); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_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 <ACE_CString, Chained_Artifacts> * 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); + } + throw; + } + +} + +void +CIAO::DomainApplicationManager_Impl:: +post_finishLaunch (void) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + try + { + // For each "external" component... + CORBA::ULong length = this->shared_->length (); + for (CORBA::ULong j = 0; j < length; ++j) + { + // Construct <Component_Binding_Info> 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 <finalize_global_binding> on ExecutionManager + this->execution_manager_->finalize_global_binding ( + *binding, true); + + delete binding; + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::post_finishLaunch.\n"); + throw; + } + +} + +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. + ACE_CString::size_type pos = child_uuid.find ('@'); + + retv->plan_uuid_ = + child_uuid.substring (0, pos); + + retv->node_ = + child_uuid.substring (pos + 1, + ACE_CString::npos); // 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 + <ACE_CString, + Chained_Artifacts> *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]; + + 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) +{ + 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)) + 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_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 only 1 internalEndpoint, then we know it's through event service. + if (binding_len == 1) + { + return + this->handle_es_connection (instname, + binding, + plan, + retv); + } + 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 = CORBA::string_dup ("CIAO_ES"); + + // We need to populate the actual filter and store it into + // the <connection.config> 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 + // We need to populate the <endpoint> field of this connection, which + // is the object reference of this event consumer port. + if (endpoint.kind == Deployment::EventConsumer) + { + // 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_THROW_SPEC ((CORBA::SystemException, + ::Deployment::StartError)) +{ + CIAO_TRACE("CIAO::DomainApplicationManager_Impl::start"); + + try + { + CORBA::ULong i; + + for (i = 0; i < this->num_child_plans_; ++i) + { + // Get the NodeApplication object reference. + ACE_Hash_Map_Entry <ACE_CString, Chained_Artifacts> *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::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]; + + throw Deployment::StartError( + "DomainApplicationManager_Impl:startLaunch", + error.c_str ()); + } + + ::Deployment::NodeApplication_ptr my_na = + (entry->int_id_).node_application_.in (); + + my_na->ciao_preactivate (); + } + + // 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 <ACE_CString, Chained_Artifacts> *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 ())); + + throw Deployment::StartError (); + } + + ::Deployment::NodeApplication_ptr my_na = + (entry->int_id_).node_application_.in (); + + my_na->start (); + } + + // 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 <ACE_CString, Chained_Artifacts> *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]; + + throw Deployment::StartError( + "DomainApplicationManager_Impl:startLaunch", + error.c_str ()); + } + + ::Deployment::NodeApplication_ptr my_na = + (entry->int_id_).node_application_.in (); + + my_na->ciao_postactivate (); + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("DomainApplicationManager_Impl::start\t\n"); + throw; + } + +} + +void +CIAO::DomainApplicationManager_Impl:: +destroyApplication () + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::StopError)) +{ + CIAO_TRACE("CIAO::DomainApplicationManager_Impl::destroyApplication"); + try + { + // Passivate shared components also, which should delegate to EM to handle + this->passivate_shared_components (); + + // Passivate all components associated with the plan + for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) + { + ACE_Hash_Map_Entry <ACE_CString, Chained_Artifacts> *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]; + + throw + (Deployment::StopError + ("DomainApplicationManager_Impl::destroyApplication", + error.c_str ())); + } + ACE_DEBUG ((LM_DEBUG, "DAM_Impl: Invoking passivate on %s\n", + this->node_manager_names_[i].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 (); + } + + // Remove all connections associated with the plan + for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) + { + ACE_Hash_Map_Entry <ACE_CString, Chained_Artifacts> *entry = 0; + + this->artifact_map_.find (this->node_manager_names_[i], entry); + + 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); + + // 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 <connections>, + // (1) If this is a shared component, then we remove this connection + // from <connections> 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 + ACE_CString inst_name = connections[j].instanceName.in (); + CIAO::Component_Binding_Info * + binding = this->populate_binding_info (inst_name.c_str ()); + + this->execution_manager_->finalize_global_binding ( + *binding, false); + + // Remove all the connections whose "source" component + // is this component instance from the <connections> list + this->purge_connections (connections, + inst_name.c_str ()); + } + } + + if (connections->length () > 0) + { + entry->int_id_.node_application_->finishLaunch + (connections.in (), + true, // "true" ==> start the components + false // "false" => remove connections + ); + } + + } + + // After all the connections are removed, we actually destroy + for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) + { + ACE_Hash_Map_Entry <ACE_CString, Chained_Artifacts> *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_); + } + + // ?? + // 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). + + // We should again activate those shared components + this->activate_shared_components (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::destroyApplication\t\n"); + throw; + } + +} + +void +CIAO::DomainApplicationManager_Impl:: +destroyManager () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)) +{ + CIAO_TRACE("CIAO::DomainApplicationManager_Impl::destroyManager"); + try + { + for (CORBA::ULong i = 0; i < this->num_child_plans_; ++i) + { + // Get the NodeManager and NodeApplicationManager object references. + ACE_Hash_Map_Entry + <ACE_CString, + Chained_Artifacts> *entry = 0; + + if (this->artifact_map_.find (this->node_manager_names_[i], + entry) != 0) + 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 ()); + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::destroyManager\t\n"); + throw; + } + +} + +void +CIAO::DomainApplicationManager_Impl:: +perform_redeployment ( + const Deployment::DeploymentPlan & plan) + 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; + + 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 + // <finishLaunch> on the NodeApplication to accomplish this. + this->finishLaunch (true, true); // true means start activation also. + // ture means "ReDaC" is desired + + this->start (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::perform_redeployment\t\n"); + this->plan_ = this->old_plan_; + throw; + } +} + + +// Returns the DeploymentPlan associated with this ApplicationManager. +::Deployment::DeploymentPlan * +CIAO::DomainApplicationManager_Impl:: +getPlan () + 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; + + 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 (); +} + +void +CIAO::DomainApplicationManager_Impl:: +passivate_shared_components (void) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + try + { + // For each "external" component... + CORBA::ULong length = this->shared_->length (); + for (CORBA::ULong j = 0; j < length; ++j) + { + // Construct <Component_Binding_Info> 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 <finalize_global_binding> on ExecutionManager + this->execution_manager_->passivate_shared_components ( + *binding); + + delete binding; + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::passivate_shared_components.\n"); + throw; + } + +} + +void +CIAO::DomainApplicationManager_Impl:: +activate_shared_components (void) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + try + { + // For each "external" component... + CORBA::ULong length = this->shared_->length (); + for (CORBA::ULong j = 0; j < length; ++j) + { + // Construct <Component_Binding_Info> 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 <finalize_global_binding> on ExecutionManager + this->execution_manager_->activate_shared_components ( + *binding); + + delete binding; + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ( + "DomainApplicationManager_Impl::activate_shared_components.\n"); + throw; + } + +} + +void +CIAO::DomainApplicationManager_Impl:: +purge_connections (Deployment::Connections_var & connections, + const char * inst) +{ + CORBA::ULong total_len = connections->length (); + + for (CORBA::ULong i = 0; i < total_len; ++i) + { + bool found = false; + + // Remove all the connections whose "source" component + // name is <inst> + if (ACE_OS::strcmp (connections[i].instanceName.in (), + inst) == 0) + { + found = true; + + for (CORBA::ULong j = i; j < total_len - 1; ++j) + { + connections[j] = connections[j + 1]; + } + connections->length (total_len - 1); + } + + if (found) + this->purge_connections (connections, inst); + } +} + +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 * 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; +} diff --git a/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.h b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.h new file mode 100644 index 00000000000..f9ebd9dba06 --- /dev/null +++ b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.h @@ -0,0 +1,504 @@ +//================================================================== +/** + * @file DomainApplicationManager_Impl.h + * + * $Id$ + * + * This file contains implementation for the servant of + * Deployment::DomainApplicationManager. + * + * @author Gan Deng <gan.deng@vanderbilt.edu> + * @author Arvind S. Krishna <arvindk@dre.vanderbilt.edu> + * @author Tao Lu <lu@dre.vanderbilt.edu> + */ +//===================================================================== + +#ifndef CIAO_DOMAINAPPLICATIONMANAGER_IMPL_H +#define CIAO_DOMAINAPPLICATIONMANAGER_IMPL_H +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +#include "ace/Hash_Map_Manager.h" +#include "ace/Vector_T.h" +#include "ace/Functor.h" +#include "ace/OS_NS_string.h" + +#include "ciao/Deployment_DomainApplicationManagerS.h" +#include "ciao/Deployment_common.h" + +#include "tao/Valuetype/ValueBase.h" +#include "tao/Valuetype/Valuetype_Adapter_Impl.h" + +#include "ciao/CIAO_common.h" +#include "ciao/Deployment_EventsC.h" + +#include "Deployment_Configuration.h" +#include "DomainApplicationManager_Export.h" + +namespace CIAO +{ + namespace Execution_Manager + { + class Execution_Manager_Impl; + } + + /** + * @class DomainApplicationManager_Impl + * + * @brief A servant for the Deployment::DomainApplicationManager + * interface. The DomainApplicationManager is responsible for + * deploying an application on the domain level, i.e. across + * nodes. It specializes the ApplicationManager abstract interface. + */ + class DomainApplicationManager_Export DomainApplicationManager_Impl + : public virtual POA_Deployment::DomainApplicationManager + { + public: + + /// External_Connections means we search all the connections including + /// the connectiosn for external/shared components of this plan which hold + /// port objrefs of components within this plan + enum Connection_Search_Type + { + External_Connections, + Internal_Connections + }; + + /// Define the type which contains a list of DnC artifacts. + /// @@ Assumption: Each NodeApplicationManager create only one + /// NodeApplication when the startLaunch() operation is invoked, + /// which means all the nodes on that child plan are collocated in + /// the same process. + typedef struct _chained_artifacts + { + ::Deployment::NodeManager_var node_manager_; + ::Deployment::DeploymentPlan_var child_plan_; + ::Deployment::NodeApplicationManager_var node_application_manager_; + ::Deployment::NodeApplication_var node_application_; + ::Deployment::DeploymentPlan_var old_child_plan_; + } Chained_Artifacts; + + /// Constructor + 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)); + + + /*=========================================================== + * Below are helper methods for the DomainApplicationManager + * + *============================================================*/ + /** + * Initialize the DomainApplicationManager. + * @para em A pointer to the ExecutionManager servant C++ object. + * + * (1) Set the total number of child plans. + * (2) Set the list of NodeManager names, which is an array of strings. + * The <node_manager_names> is a pointer to an array of ACE_CString + * objets, which is allocated by the caller and deallocated by the + * DomainApplicationManager destructor. + * (3) Check the validity of the deployment plan and the deployment + * information data file. + * (4) Call split_plan () member function. + * (5) Invoke all the preparePlan () operations on all the corresponding + * NodeManagers with child plans. + * + * + * @@ What else do we need to initialize here? + */ + void init () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::PlanError)); + + /** + * set_uuid method on the DomainApplicationManager assigns the + * UUID of the associated plan to this Manager. This helps in + * reverse lookup operations such as given a manager, obtaining + * the UUID associated. The get_uuid method is used in this case. + */ + void set_uuid (const char * uuid); + + const char * get_uuid () const; + + /*=========================================================== + * Below are operations from the DomainApplicationManager + * + *============================================================*/ + + /** + * Fetch the NodeApplication object reference based on the NodeManager name. + */ + virtual Deployment::NodeApplication_ptr get_node_app ( + const char * node_name) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Deployment::NoSuchName)); + + /** + * Executes the application, but does not start it yet. Users can + * optionally provide launch-time configuration properties to + * override properties that are part of the plan. Raises the + * InvalidProperty exception if a configuration property is + * invalid. Raises the StartError exception if an error occurs + * during launching. Raises the ResourceNotAvailable exception if + * the commitResources parameter to the prepare operation of the + * ExecutionManager was true, if late resource allocation is used, + * and one of the requested resources is not available. + */ + virtual void + startLaunch (const ::Deployment::Properties & configProperty, + ::CORBA::Boolean start) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::ResourceNotAvailable, + ::Deployment::StartError, + ::Deployment::InvalidProperty)); + + /** + * The second step in launching an application in the + * domain-level. If the start parameter is true, the application + * is started as well. Raises the StartError exception if + * launching or starting the application fails. + */ + virtual void finishLaunch (CORBA::Boolean start, + CORBA::Boolean is_ReDAC) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::StartError)); + + /** + * The last step in launching an application in the + * domain-level. We establish connection bindings + * for external/shared components of this deployment plan + * components. + * Internally, this operation will invoke some operations + * on ExecutionManager to finish up this task. + */ + virtual void post_finishLaunch (void) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + virtual void passivate_shared_components (void) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + virtual void activate_shared_components (void) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + /** + * Starts the application. Raises the StartError exception if + * starting the application fails. + */ + virtual void start () + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::StartError)); + + /** + * Terminates a running application. Raises the StopError + * exception if an error occurs during termination. Raises the + * InvalidReference exception if the appliction reference is + * unknown. + */ + virtual void destroyApplication () + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::StopError)); + + /** + * Returns the DeploymentPlan associated with this ApplicationManager. + */ + virtual ::Deployment::DeploymentPlan * getPlan () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * This is a helper function to destroy the NodeAppManager. + * Since we don't want to do so in the destructor so we will + * ask the ExecutionManager to do this on us when the same IDL + * op invoked on it. This is part of the result for merging DAM + * with DA. + */ + virtual void destroyManager () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)); + + // 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, + ::Components::RemoveFailure)); + + protected: + /// Destructor + virtual ~DomainApplicationManager_Impl (void); + + /** + * (1) Parse the global deployment plan, get the total number of + * child plans included in the global plan, and get the list of + * names of NodeManagers for each child plan. + * (2) Check whether all the NodeManager names are present in the + * deployment information data file. + */ + bool get_plan_info (void); + + /** + * Split the global (domain-level) deployment plan to a set of + * local (node-level) deployment plans. The set of local plans + * are cached in the ACE hash map member variable. + * Also, fill in the <node_manager_> field of the Chained_Artifacts + * struct. + */ + int split_plan (void); + + /** + * Construct <Component_Binding_Info> struct for the component instance. + * + * @param name component instance name + * @param child_uuid child plan uuid string + */ + CIAO::Component_Binding_Info * + populate_binding_info (const ACE_CString& name, + const ACE_CString& child_uuid); + + /** + * Construct <Component_Binding_Info> struct for the component instance. + * Fetch the plan_uuid info from the internally cached shared component + * list. + * + * @param name component instance name + */ + CIAO::Component_Binding_Info * + populate_binding_info (const ACE_CString& name); + + /** + * Contact each NodeManager to get shared compnents information + * and then update its internal cache. + */ + void synchronize_shared_components_with_node_managers (void); + + /** + * A helper function to add a list of shared components into + * the cached shared component list. + * + * @param shared A list of shared components to be added. + */ + void add_shared_components (const Deployment::ComponentPlans & shared); + + /** + * A private function to check whether a component is in the shared + * component list. + * + * @param name The name of a component instance. + */ + bool is_shared_component (const char * name); + + /** + * Cache the incoming connections, which is a sequence of Connections, + * into the <all_connections_> list. + */ + void add_connections (const Deployment::Connections & incoming_conn); + + /** + * Given a child deployment plan, find the <Connections> sequence + * of the "providedReference" for the component instances in the + * child deployment plan as Receiver side. + * By default, we search in the new plan. + * + * If <is_getting_all_connections> is false, then we only + * search for "new connections" (valid for ReDaC case only). + * Otherwise, we will search for both new connections and those + * already existing connections. + */ + Deployment::Connections * + get_outgoing_connections (const Deployment::DeploymentPlan &plan, + bool is_getting_all_connections = true, + bool is_search_new_plan = true, + Connection_Search_Type t = Internal_Connections); + + /// This is a helper function to find the connection for a component. + bool + get_outgoing_connections_i (const char * instname, + Deployment::Connections & retv, + bool is_ReDAC, + bool is_search_new_plan) + ACE_THROW_SPEC ((Deployment::StartError)); + + bool + populate_connection_for_binding ( + const char * instname, + const Deployment::PlanConnectionDescription & binding, + const Deployment::DeploymentPlan & plan, + Deployment::Connections & retv) + ACE_THROW_SPEC ((Deployment::StartError)); + + bool + handle_es_connection ( + const char * instname, + const Deployment::PlanConnectionDescription & binding, + const Deployment::DeploymentPlan & plan, + Deployment::Connections & retv) + ACE_THROW_SPEC ((Deployment::StartError)); + + bool + handle_direct_connection ( + const char * instname, + const Deployment::PlanConnectionDescription & binding, + const Deployment::DeploymentPlan & plan, + Deployment::Connections & retv) + ACE_THROW_SPEC ((Deployment::StartError)); + + /// Dump connections, a static method + void dump_connections (const ::Deployment::Connections & connections); + + /// Check whether a connection already exists in the cached old plan + bool already_exists (const Deployment::PlanConnectionDescription & conn); + + /// Remove those appeared in <right> from the <left> + Deployment::Connections * + subtract_connections (const Deployment::Connections & left, + const Deployment::Connections & right); + + void + purge_connections (Deployment::Connections_var & connections, + const char * inst); + + /** + * The first step in finish_launching an application in the + * domain-level. We install all the CIAO_Event_Service objects + * as specified in the DeploymentPlan. + * Internally, this operation will invoke an operation on each cached + * NodeApplication object. + */ + virtual void install_all_es (void) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + /** + * Add all CIAO_Event_Service objects into the cached map. + */ + virtual void + add_es_to_map (const char* node_name, + CIAO::CIAO_Event_Service * ciao_es) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + /** + * Get the actual event connection QoS properties based on the + * deployment requirement. The deployment requirement only specifies + * an identifier/reference to the EventServiceDeploymentDescriptions. + */ + virtual const Deployment::Properties * + get_connection_QoS_configuration ( + const Deployment::Requirement & requirement); + + protected: + /// location of the Domainapplication + CORBA::String_var domainapp_path_; + + /// Keep a pointer to the managing ORB serving this servant. + CORBA::ORB_var orb_; + + /// Keep a pointer to the managing POA. + PortableServer::POA_var poa_; + + /// Pointer to the ExecutionManager_Impl "singleton" servant object + /// We could do this because ExecutionManager and DomainApplicationManager + /// are always collocated in the same process, so we don't have + /// to pass CORBA object reference back and forth. + Execution_Manager::Execution_Manager_Impl * execution_manager_; + + /// Cache a list of shared components + Deployment::ComponentPlans_var shared_; + + /// Cache the ior of the previous reference + CORBA::String_var ior_; + + /// Cached TargetManager. + Deployment::TargetManager_var target_manager_; + + /// Cached deployment plan for the particular domain. + /// The plan will be initialized when init is called. + Deployment::DeploymentPlan plan_; + + /// Cached old deployment plan, i.e., before redeployment + Deployment::DeploymentPlan old_plan_; + + /// Cached child plans. + //Deployment::DeploymentPlan * child_plan_; + + /// Total number of child deployment plans. + size_t num_child_plans_; + + /// The list of node manager names, each of them + /// corresponds to one child plan. + ACE_Vector<ACE_CString> node_manager_names_; + + /// Cached information for NodeManager, NodeApplicationManager, + /// NodeApplication, Connections, etc. + /// Key: NodeManager name with CString type. + /// Value: Chained_Artifacts struct type. + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + Chained_Artifacts, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> Chained_Artifacts_Table; + + Chained_Artifacts_Table artifact_map_; + + /// Cached information of all the CIAO_Event_Service objects within + /// the deployment plan + /// Key: the string identifier of the CIAO_Event_Service + /// Value: the object reference of the CIAO_Event_Service + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + CIAO::CIAO_Event_Service_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> Event_Service_Table; + + Event_Service_Table es_map_; + + /// The deployment information data file. + const char * deployment_file_; + + /// Deployment Configuration info, which contains the deployment topology. + Deployment_Configuration deployment_config_; + + /// UUID from the Plan + CORBA::String_var uuid_; + + /// Maintain a list of <Connections>, each of which is obtained by + /// calling the startLaunch() method on the NodeApplicationManager object. + ::Deployment::Connections_var all_connections_; + + /// This variable is used to control the execution path of some + /// member function implementations. The reason is because we want + /// to avoid unnecessary code duplicate. The default value is "false". + bool is_redeployment_; + + /// Cache the CIAO_Event_Service deployment description + CIAO::DAnCE::EventServiceDeploymentDescriptions_var esd_; + }; +} + +#if defined (__ACE_INLINE__) +# include "DomainApplicationManager_Impl.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* CIAO_DOMAINAPPLICATIONMANAGER_IMPL_H */ diff --git a/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.inl b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.inl new file mode 100644 index 00000000000..b50adfbc712 --- /dev/null +++ b/modules/CIAO/DAnCE/DomainApplicationManager/DomainApplicationManager_Impl.inl @@ -0,0 +1,16 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE const char * +CIAO::DomainApplicationManager_Impl::get_uuid () const +{ + return this->uuid_; +} + +ACE_INLINE void +CIAO::DomainApplicationManager_Impl::set_uuid (const char * uuid) +{ + // Copy this uuid reference + this->uuid_ = CORBA::string_dup (uuid); +} 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 */ diff --git a/modules/CIAO/DAnCE/Interfaces/ExecutionManagerDaemon.idl b/modules/CIAO/DAnCE/Interfaces/ExecutionManagerDaemon.idl new file mode 100644 index 00000000000..01942fd3afa --- /dev/null +++ b/modules/CIAO/DAnCE/Interfaces/ExecutionManagerDaemon.idl @@ -0,0 +1,25 @@ +// $Id$ + +/** + * @file ExecutionManagerDaemon.idl + * + * @brief Simple interface to control the ExecutionManager. This + * interface currently provides an additional method called shutdown + * to terminate the process cleanly. + */ + +#include "ciao/Deployment_ExecutionManager.idl" + +module CIAO +{ + /** + * @brief CIAO Execution Manager Program + * + * This feature addition is added using inheritance mechanism currently + */ + interface ExecutionManagerDaemon : Deployment::ExecutionManager + { + // Shutdown the daemon process. + oneway void shutdown (); + }; +}; diff --git a/modules/CIAO/DAnCE/Interfaces/ExecutionManager_stub_export.h b/modules/CIAO/DAnCE/Interfaces/ExecutionManager_stub_export.h new file mode 100644 index 00000000000..f32c91c5e6e --- /dev/null +++ b/modules/CIAO/DAnCE/Interfaces/ExecutionManager_stub_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl ExecutionManager_stub +// ------------------------------ +#ifndef EXECUTIONMANAGER_STUB_EXPORT_H +#define EXECUTIONMANAGER_STUB_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (EXECUTIONMANAGER_STUB_HAS_DLL) +# define EXECUTIONMANAGER_STUB_HAS_DLL 1 +#endif /* ! EXECUTIONMANAGER_STUB_HAS_DLL */ + +#if defined (EXECUTIONMANAGER_STUB_HAS_DLL) && (EXECUTIONMANAGER_STUB_HAS_DLL == 1) +# if defined (EXECUTIONMANAGER_STUB_BUILD_DLL) +# define ExecutionManager_stub_Export ACE_Proper_Export_Flag +# define EXECUTIONMANAGER_STUB_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define EXECUTIONMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* EXECUTIONMANAGER_STUB_BUILD_DLL */ +# define ExecutionManager_stub_Export ACE_Proper_Import_Flag +# define EXECUTIONMANAGER_STUB_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define EXECUTIONMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* EXECUTIONMANAGER_STUB_BUILD_DLL */ +#else /* EXECUTIONMANAGER_STUB_HAS_DLL == 1 */ +# define ExecutionManager_stub_Export +# define EXECUTIONMANAGER_STUB_SINGLETON_DECLARATION(T) +# define EXECUTIONMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* EXECUTIONMANAGER_STUB_HAS_DLL == 1 */ + +// Set EXECUTIONMANAGER_STUB_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (EXECUTIONMANAGER_STUB_NTRACE) +# if (ACE_NTRACE == 1) +# define EXECUTIONMANAGER_STUB_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define EXECUTIONMANAGER_STUB_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !EXECUTIONMANAGER_STUB_NTRACE */ + +#if (EXECUTIONMANAGER_STUB_NTRACE == 1) +# define EXECUTIONMANAGER_STUB_TRACE(X) +#else /* (EXECUTIONMANAGER_STUB_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define EXECUTIONMANAGER_STUB_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (EXECUTIONMANAGER_STUB_NTRACE == 1) */ + +#endif /* EXECUTIONMANAGER_STUB_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/Interfaces/Interfaces.mpc b/modules/CIAO/DAnCE/Interfaces/Interfaces.mpc new file mode 100644 index 00000000000..00f5b5192d9 --- /dev/null +++ b/modules/CIAO/DAnCE/Interfaces/Interfaces.mpc @@ -0,0 +1,39 @@ +// -*- MPC -*- +// $Id$ + +project (ExecutionManager_stub): ciao_deployment_stub { + + sharedname = ExecutionManager_stub + + idlflags += -Wb,stub_export_macro=ExecutionManager_stub_Export + idlflags += -Wb,stub_export_include=ExecutionManager_stub_export.h + + dynamicflags = EXECUTIONMANAGER_STUB_BUILD_DLL + + IDL_Files { + ExecutionManagerDaemon.idl + } + + Source_Files { + ExecutionManagerDaemonC.cpp + } +} + +project (NodeManager_stub): ciao_deployment_stub { + sharedname = NodeManager_stub + + idlflags += -Wb,stub_export_macro=NodeManager_stub_Export + idlflags += -Wb,stub_export_include=NodeManager_stub_export.h + idlflags += -Wb,skel_export_macro=NodeManager_svnt_Export + idlflags += -Wb,skel_export_include=NodeManager_svnt_export.h + + dynamicflags = NODEMANAGER_STUB_BUILD_DLL + + IDL_Files { + NodeManagerDaemon.idl + } + + Source_Files { + NodeManagerDaemonC.cpp + } +} diff --git a/modules/CIAO/DAnCE/Interfaces/NodeManagerDaemon.idl b/modules/CIAO/DAnCE/Interfaces/NodeManagerDaemon.idl new file mode 100644 index 00000000000..617df0f080f --- /dev/null +++ b/modules/CIAO/DAnCE/Interfaces/NodeManagerDaemon.idl @@ -0,0 +1,35 @@ +// $Id$ + +/** + * @file NodeManagerDaemon.idl + * + * @brief Controling interface for managing and controling CIAO daemon. + */ + +#include "ciao/Deployment_NodeManager.idl" +#include "ciao/Deployment_NodeApplicationManager.idl" + +module CIAO +{ + /** + * @brief CIAO daemon process control program. + * + * @@The Inheritage might cause binary code bloating but + * it's an easy way of combining features. In the future we could + * move this definition into Deployment.idl. + */ + interface NodeManagerDaemon : Deployment::NodeManager + { + // Canonical name of this daemon + readonly attribute string name; + + // Shutdown the daemon process. + oneway void shutdown (); + + /// RACE specific extension. + /// Modify the priority of a node application process. + long set_priority (in string plan_id, + in string cid, + in ::Deployment::Sched_Params nm_params); + }; +}; diff --git a/modules/CIAO/DAnCE/Interfaces/NodeManager_stub_export.h b/modules/CIAO/DAnCE/Interfaces/NodeManager_stub_export.h new file mode 100644 index 00000000000..3e708b0ab1f --- /dev/null +++ b/modules/CIAO/DAnCE/Interfaces/NodeManager_stub_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl NodeManager_stub +// ------------------------------ +#ifndef NODEMANAGER_STUB_EXPORT_H +#define NODEMANAGER_STUB_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (NODEMANAGER_STUB_HAS_DLL) +# define NODEMANAGER_STUB_HAS_DLL 1 +#endif /* ! NODEMANAGER_STUB_HAS_DLL */ + +#if defined (NODEMANAGER_STUB_HAS_DLL) && (NODEMANAGER_STUB_HAS_DLL == 1) +# if defined (NODEMANAGER_STUB_BUILD_DLL) +# define NodeManager_stub_Export ACE_Proper_Export_Flag +# define NODEMANAGER_STUB_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define NODEMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* NODEMANAGER_STUB_BUILD_DLL */ +# define NodeManager_stub_Export ACE_Proper_Import_Flag +# define NODEMANAGER_STUB_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define NODEMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* NODEMANAGER_STUB_BUILD_DLL */ +#else /* NODEMANAGER_STUB_HAS_DLL == 1 */ +# define NodeManager_stub_Export +# define NODEMANAGER_STUB_SINGLETON_DECLARATION(T) +# define NODEMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* NODEMANAGER_STUB_HAS_DLL == 1 */ + +// Set NODEMANAGER_STUB_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (NODEMANAGER_STUB_NTRACE) +# if (ACE_NTRACE == 1) +# define NODEMANAGER_STUB_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define NODEMANAGER_STUB_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !NODEMANAGER_STUB_NTRACE */ + +#if (NODEMANAGER_STUB_NTRACE == 1) +# define NODEMANAGER_STUB_TRACE(X) +#else /* (NODEMANAGER_STUB_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define NODEMANAGER_STUB_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (NODEMANAGER_STUB_NTRACE == 1) */ + +#endif /* NODEMANAGER_STUB_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/Interfaces/NodeManager_svnt_export.h b/modules/CIAO/DAnCE/Interfaces/NodeManager_svnt_export.h new file mode 100644 index 00000000000..199168ef44d --- /dev/null +++ b/modules/CIAO/DAnCE/Interfaces/NodeManager_svnt_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl NodeManager_svnt +// ------------------------------ +#ifndef NODEMANAGER_SVNT_EXPORT_H +#define NODEMANAGER_SVNT_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (NODEMANAGER_SVNT_HAS_DLL) +# define NODEMANAGER_SVNT_HAS_DLL 1 +#endif /* ! NODEMANAGER_SVNT_HAS_DLL */ + +#if defined (NODEMANAGER_SVNT_HAS_DLL) && (NODEMANAGER_SVNT_HAS_DLL == 1) +# if defined (NODEMANAGER_SVNT_BUILD_DLL) +# define NodeManager_svnt_Export ACE_Proper_Export_Flag +# define NODEMANAGER_SVNT_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define NODEMANAGER_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* NODEMANAGER_SVNT_BUILD_DLL */ +# define NodeManager_svnt_Export ACE_Proper_Import_Flag +# define NODEMANAGER_SVNT_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define NODEMANAGER_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* NODEMANAGER_SVNT_BUILD_DLL */ +#else /* NODEMANAGER_SVNT_HAS_DLL == 1 */ +# define NodeManager_svnt_Export +# define NODEMANAGER_SVNT_SINGLETON_DECLARATION(T) +# define NODEMANAGER_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* NODEMANAGER_SVNT_HAS_DLL == 1 */ + +// Set NODEMANAGER_SVNT_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (NODEMANAGER_SVNT_NTRACE) +# if (ACE_NTRACE == 1) +# define NODEMANAGER_SVNT_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define NODEMANAGER_SVNT_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !NODEMANAGER_SVNT_NTRACE */ + +#if (NODEMANAGER_SVNT_NTRACE == 1) +# define NODEMANAGER_SVNT_TRACE(X) +#else /* (NODEMANAGER_SVNT_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define NODEMANAGER_SVNT_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (NODEMANAGER_SVNT_NTRACE == 1) */ + +#endif /* NODEMANAGER_SVNT_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/Interfaces/README b/modules/CIAO/DAnCE/Interfaces/README new file mode 100644 index 00000000000..0118689ad70 --- /dev/null +++ b/modules/CIAO/DAnCE/Interfaces/README @@ -0,0 +1,2 @@ +To resolve the MPC issue of directory dependency, we have to put some IDL +files into a separate directory. This directory servers for this purpose. diff --git a/modules/CIAO/DAnCE/NodeApplication/CIAO_NodeApplication_export.h b/modules/CIAO/DAnCE/NodeApplication/CIAO_NodeApplication_export.h new file mode 100644 index 00000000000..b9ebab3d7cb --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/CIAO_NodeApplication_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl NODEAPPLICATION +// ------------------------------ +#ifndef NODEAPPLICATION_EXPORT_H +#define NODEAPPLICATION_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (NODEAPPLICATION_HAS_DLL) +# define NODEAPPLICATION_HAS_DLL 1 +#endif /* ! NODEAPPLICATION_HAS_DLL */ + +#if defined (NODEAPPLICATION_HAS_DLL) && (NODEAPPLICATION_HAS_DLL == 1) +# if defined (NODEAPPLICATION_BUILD_DLL) +# define NODEAPPLICATION_Export ACE_Proper_Export_Flag +# define NODEAPPLICATION_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define NODEAPPLICATION_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* NODEAPPLICATION_BUILD_DLL */ +# define NODEAPPLICATION_Export ACE_Proper_Import_Flag +# define NODEAPPLICATION_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define NODEAPPLICATION_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* NODEAPPLICATION_BUILD_DLL */ +#else /* NODEAPPLICATION_HAS_DLL == 1 */ +# define NODEAPPLICATION_Export +# define NODEAPPLICATION_SINGLETON_DECLARATION(T) +# define NODEAPPLICATION_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* NODEAPPLICATION_HAS_DLL == 1 */ + +// Set NODEAPPLICATION_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (NODEAPPLICATION_NTRACE) +# if (ACE_NTRACE == 1) +# define NODEAPPLICATION_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define NODEAPPLICATION_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !NODEAPPLICATION_NTRACE */ + +#if (NODEAPPLICATION_NTRACE == 1) +# define NODEAPPLICATION_TRACE(X) +#else /* (NODEAPPLICATION_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define NODEAPPLICATION_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (NODEAPPLICATION_NTRACE == 1) */ + +#endif /* NODEAPPLICATION_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/NodeApplication/Configurator_Factory.cpp b/modules/CIAO/DAnCE/NodeApplication/Configurator_Factory.cpp new file mode 100644 index 00000000000..5de92094ee8 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/Configurator_Factory.cpp @@ -0,0 +1,138 @@ +// $Id$ + +#include "Configurator_Factory.h" +#include "NoOp_Configurator.h" +#include "ace/Null_Mutex.h" +#include "ciao/CIAO_common.h" +#include "ace/Arg_Shifter.h" + +int +CIAO::NodeApplication_Options::parse_args (int &argc, char *argv[]) +{ + ACE_Arg_Shifter shifter (argc, argv); + + while (shifter.is_anything_left ()) + { + const char *parm = 0; + + if (shifter.cur_arg_strncasecmp ("-n") == 0) // Use callback. + { + this->use_callback_ = false; + shifter.consume_arg (); + } + else if (shifter.cur_arg_strncasecmp ("-r") == 0) + { + this->rt_support_ = true; + shifter.consume_arg (); + } + else if (ACE_OS::strncmp (shifter.get_current (), + "-ORB", + ACE_OS::strlen ("-ORB")) == 0) + { + // Ignore ORB parameter + shifter.ignore_arg (); + } + else if (shifter.cur_arg_strncasecmp ("-o") == 0) + { + // This double checking is necessary to avoid the Arg_Shifter from + // mistaking any -ORBxxx flag as -o flag. + if ((parm = shifter.get_the_parameter ("-o")) !=0) + { + this->ior_output_filename_ = parm; + } + shifter.consume_arg (); + } + else if ((parm = shifter.get_the_parameter ("-k")) !=0) + { + this->callback_ior_ = parm; + shifter.consume_arg (); + } + else if (shifter.cur_arg_strncasecmp ("-h") == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s\n" + "-n Do not use Callback (for testing)\n" + "-o <ior_output_file>\n" + "-k <NodeApplicationManager_callback_ior>\n" + "-r Request RT support\n" + "-h Usage help" + "\n", + argv [0]), + -1); + shifter.consume_arg (); + } + else + { + shifter.ignore_arg (); + } + } + + if (this->use_callback_ && 0 == this->callback_ior_.length ()) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Callback IOR to NodeApplicationManager " + "is required.\n"), + -1); + } + + return 0; +} + +CIAO::NodeApp_Configurator * +CIAO::NodeApplication_Options::create_nodeapp_configurator (void) +{ + typedef CIAO::NodeApp_Configurator * (*intelligent_designer)(void); + CIAO::NodeApp_Configurator* ptr = 0; + + if (this->rt_support_) + { + int const retval = + this->config_dll_.open ( + ACE_DLL_PREFIX ACE_TEXT ("CIAO_RTNA_Configurator"), + ACE_DEFAULT_SHLIB_MODE, + 0); + + if (0 != retval) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "dll.open"), + 0); + } + + // Cast the void* to non-pointer type first - it's not legal to + // cast a pointer-to-object directly to a pointer-to-function. + void *void_ptr = + this->config_dll_.symbol (ACE_TEXT ("create_nodeapp_configurator")); + ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (void_ptr); + + // "id" is for intelligent-designer. + intelligent_designer config_id = + reinterpret_cast<intelligent_designer> (tmp); + + if (0 == config_id) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%p", + "dll.symbol"), + 0); + } + + ptr = config_id (); + + if (0 == ptr) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Error creating RTNodeApp_Configurator\n"), + 0); + } + } + else + { + ACE_NEW_RETURN (ptr, + CIAO::NoOp_Configurator (), + 0); + } + + return ptr; +} diff --git a/modules/CIAO/DAnCE/NodeApplication/Configurator_Factory.h b/modules/CIAO/DAnCE/NodeApplication/Configurator_Factory.h new file mode 100644 index 00000000000..d80f12c3cee --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/Configurator_Factory.h @@ -0,0 +1,103 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Configurator_Factory.h + * + * $Id$ + * + * Configurator Factory contains the factory method for creating concret + * NodeApp_Configurator object. + * + * @author Nanbor Wang <nanbor@cs.wustl.edu> + */ +//============================================================================= + + +#ifndef CIAO_CONFIGURATOR_FACTORY_H +#define CIAO_CONFIGURATOR_FACTORY_H +#include /**/ "ace/pre.h" + +#include "CIAO_NodeApplication_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/ORB_Core.h" +#include "tao/ORB.h" +#include "ace/Task.h" +#include "ace/SString.h" +#include "ace/Auto_Ptr.h" +#include "ace/DLL.h" +#include "NodeApp_Configurator.h" + +namespace CIAO +{ + + + /** + * @class NodeApplication_Options + * + * @brief An class for managing and extracting command line options + * for NodeApplication. + * + * @note We currently support loading one single external module for + * RT support. Perhaps how this should really be done is to allow + * the NodeApplication_Core to load up a list of external modules + * (in DLLs or otherwise) and call the corresponding init methods in + * sequence. This way, we open up the component server so system + * developers can plug in their own system configuration needs into + * the whole system. + */ + class NODEAPPLICATION_Export NodeApplication_Options + { + public: + // default ctor. + NodeApplication_Options () : use_callback_ (true), rt_support_ (false) {} + + /// extracting commandline arguments + int parse_args (int &argc, char *argv[]); + + NodeApp_Configurator *create_nodeapp_configurator (void); + + bool use_callback () {return this->use_callback_; } + + bool rt_support () {return this->rt_support_; } + + int write_ior_file () + { return (this->ior_output_filename_.length () != 0); } + + const char *ior_output_filename () + { return this->ior_output_filename_.c_str (); } + + const char *callback_ior () + { return this->callback_ior_.c_str (); } + + private: + /// The name of the file to write stringified IOR to. + ACE_CString ior_output_filename_; + + /// Stringified IOR of a CIAO's callback object. + ACE_CString callback_ior_; + + /// CIAO ComponentServer uses the callback object to pass it's + /// own object reference back to NodeApplicationManager. + bool use_callback_; + + /// If we need to support RT-CORBA. Currently, this is + /// mandatory, but we can probably allow some sort of + /// "best-effort" RT support. I.e., if the platform/environment + /// doesn't support RT, then we will still deploy the NodeApp but + /// ignore the RT spec. Perhaps something in the future. + bool rt_support_; + + // For managing dynamically loaded configurator library + ACE_DLL config_dll_; + }; + +} + + +#include /**/ "ace/post.h" +#endif /* CIAO_CONFIGURATOR_FACTORY_H */ diff --git a/modules/CIAO/DAnCE/NodeApplication/Container_Impl.cpp b/modules/CIAO/DAnCE/NodeApplication/Container_Impl.cpp new file mode 100644 index 00000000000..89cab7af662 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/Container_Impl.cpp @@ -0,0 +1,609 @@ +// $Id$ + +#include "Container_Impl.h" +#include "ciao/CCM_StandardConfiguratorC.h" +#include "ciao/CCM_KeylessCCMHomeC.h" + +#include "orbsvcs/CosNamingC.h" + +#if !defined (__ACE_INLINE__) +# include "Container_Impl.inl" +#endif /* __ACE_INLINE__ */ + +CIAO::Container_Impl::~Container_Impl () +{ + // @@ remove all components and home? + delete this->container_; +} + +PortableServer::POA_ptr +CIAO::Container_Impl::_default_POA (void) +{ + CIAO_TRACE ("CIAO::Container_Impl::_default_POA"); + return PortableServer::POA::_duplicate (this->poa_.in ()); +} + + /////////////////////////////////////////////////////////////// + +CORBA::Long +CIAO::Container_Impl::init (const CORBA::PolicyList *policies) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CIAO_TRACE ("CIAO::Container_Impl::init"); + // @@ Initialize container and create the internal container + // implementation that actually interacts with installed + // homes/components. + + // @@ We will need a container factory here later on when we support + // more kinds of container implementations. + + // @@Jai, what is the condition to create an upgradeable container? + // Where is it getting created and how? Need to address that. + + if (this->static_entrypts_maps_ == 0) + { + ACE_NEW_THROW_EX (this->container_, + CIAO::Session_Container (this->orb_.in (), this), + CORBA::NO_MEMORY ()); + } + else + { + ACE_NEW_THROW_EX (this->container_, + CIAO::Session_Container (this->orb_.in (), this, 1, + this->static_entrypts_maps_), + CORBA::NO_MEMORY ()); + } + + return this->container_->init (0, + policies); +} + + +Deployment::ComponentInfos * +CIAO::Container_Impl::install ( + const ::Deployment::ContainerImplementationInfo & container_impl_info + ) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::UnknownImplId, + ::Deployment::ImplEntryPointNotFound, + ::Deployment::InstallationFailure, + ::Components::InvalidConfiguration)) +{ + CIAO_TRACE ("CIAO::Container_Impl::install"); + Deployment::ComponentInfos_var retv; + try + { + ACE_NEW_THROW_EX (retv, + Deployment::ComponentInfos, + CORBA::NO_MEMORY ()); + + // Get the ComponentImplementationInfos from the + // ContainerImplementationInfo + // to avoid too long syntax representation + const ::Deployment::ComponentImplementationInfos impl_infos = + container_impl_info.impl_infos; + + CORBA::ULong const len = impl_infos.length (); + retv->length (len); + + for (CORBA::ULong i = 0; i < len; ++i) + { + // Install home + Components::CCMHome_var home = + this->install_home (impl_infos[i]); + + Components::KeylessCCMHome_var kh = + Components::KeylessCCMHome::_narrow (home.in ()); + + if (CORBA::is_nil (kh.in ())) + throw Deployment::InstallationFailure (); + + // Create component from home + Components::CCMObject_var comp = + kh->create_component (); + + if (CORBA::is_nil (comp.in ())) + throw Deployment::InstallationFailure (); + + if (this->component_map_.bind + (impl_infos[i].component_instance_name.in (), + Components::CCMObject::_duplicate (comp.in ()))) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) Container_Impl.cpp -" + "CIAO::Container_Impl::install -" + "error in binding component " + "instance name [%s] into the component map \n", + impl_infos[i].component_instance_name.in ())); + throw Deployment::InstallationFailure (); + } + + // Set the return value. + (*retv)[i].component_instance_name + = impl_infos[i].component_instance_name.in (); + + (*retv)[i].component_ref = + Components::CCMObject::_duplicate (comp.in ()); + + // Deal with Component instance related Properties. + // Now I am only concerning about the COMPOENTIOR and attribute + // configuration initialization. + + // I need to map Properties to Components::ConfigValues + ::Components::ConfigValues comp_attributes; + comp_attributes.length (0); + + const CORBA::ULong clen = impl_infos[i].component_config.length (); + for (CORBA::ULong prop_len = 0; prop_len < clen; ++prop_len) + { + // Set up the ComponentIOR attribute + if (ACE_OS::strcmp + (impl_infos[i].component_config[prop_len].name.in (), + "ComponentIOR") == 0) + { + const char * path; + impl_infos[i].component_config[prop_len].value >>= path; + + CORBA::String_var ior = + this->orb_->object_to_string (comp.in ()); + + if (CIAO::Utility::write_IOR (path, ior.in ()) != 0) + { + if (CIAO::debug_level () > 1) + ACE_DEBUG ((LM_DEBUG, "Failed to write the IOR.\n")); + + throw CORBA::INTERNAL (); + } + } + + // Set up the naming service attribute + if (ACE_OS::strcmp + (impl_infos[i].component_config[prop_len].name.in (), + "RegisterNaming") == 0) + { + const char * naming_context; + impl_infos[i]. + component_config[prop_len].value >>= naming_context; + + // Register the component with the naming service + ACE_DEBUG ((LM_DEBUG, + "Register component with naming service.\n")); + bool result = + register_with_ns ( + naming_context, + this->orb_.in (), + Components::CCMObject::_duplicate (comp.in ()) + ); + + if (!result) + { + ACE_DEBUG ((LM_DEBUG, + "Failed to register with naming service.\n")); + } + else + { + if (this->naming_map_.bind + (impl_infos[i].component_instance_name.in (), + ACE_CString (naming_context))) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) Container_Impl.cpp -" + "CIAO::Container_Impl::install -" + "error in binding component " + "instance name [%s] into the naming map \n", + impl_infos[i].component_instance_name.in ())); + throw Deployment::InstallationFailure (); + } + } + + + } + + // Initialize attributes through StandardConfigurator interface + // @@Todo: Currently I have to manually map + // the Deployment::Properties to + // Components::ConfigValues, we should use a + // common data structure in + // the future. - Gan + CORBA::ULong cur_len = comp_attributes.length (); + comp_attributes.length (cur_len + 1); + + Components::ConfigValue *item = new OBV_Components::ConfigValue (); + item->name (impl_infos[i].component_config[prop_len].name.in ()); + CORBA::Any tmp = impl_infos[i].component_config[prop_len].value; + item->value (tmp); + + comp_attributes[cur_len] = item; + } + + if (comp_attributes.length () != 0) + { + //std_configurator.set_configuration + ::Components::StandardConfigurator_var std_configurator = + comp->get_standard_configurator (); + + std_configurator->set_configuration (comp_attributes); + } + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Container_Impl::install\t\n"); + throw; + } + + return retv._retn (); +} + +::Deployment::Properties * +CIAO::Container_Impl::properties () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CIAO_TRACE ("CIAO::Container_Impl::properties"); + ::Deployment::Properties *retval = 0; + + ACE_NEW_THROW_EX (retval, + ::Deployment::Properties, + CORBA::NO_MEMORY ()); + + *retval = this->properties_; + + return retval; +} + +::Deployment::NodeApplication_ptr +CIAO::Container_Impl::get_node_application () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CIAO_TRACE ("CIAO::Container_Impl::get_node_application"); + return ::Deployment::NodeApplication::_duplicate (this->nodeapp_.in ()); +} + +::Components::CCMHome_ptr +CIAO::Container_Impl::install_home ( + const ::Deployment::ComponentImplementationInfo & impl_info) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::UnknownImplId, + Deployment::ImplEntryPointNotFound, + Deployment::InstallationFailure, + Components::InvalidConfiguration)) +{ + CIAO_TRACE ("CIAO::Container_Impl::install_home"); + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) Container_Impl.cpp -" + "CIAO::Container_Impl::install_home -" + "installing home for component " + "instance [%s] \n", + impl_info.component_instance_name.in ())); + } + + Components::CCMHome_var newhome = + this->container_->ciao_install_home (impl_info.executor_dll.in (), + impl_info.executor_entrypt.in (), + impl_info.servant_dll.in (), + impl_info.servant_entrypt.in (), + impl_info.component_instance_name.in ()); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) Container_Impl.cpp -" + "CIAO::Container_Impl::install_home -" + "success in installing home for component " + "instance [%s] \n", + impl_info.component_instance_name.in ())); + } + + // We don't have to do _narrow since the generated code makes sure of + // the object type for us + // Bind the home in the map. + if (this->home_map_.bind (impl_info.component_instance_name.in (), + Components::CCMHome::_duplicate (newhome.in ()))) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) Container_Impl.cpp -" + "CIAO::Container_Impl::install_home -" + "error in binding home for component " + "instance [%s] \n", + impl_info.component_instance_name.in ())); + ACE_THROW_RETURN (Deployment::InstallationFailure (), + Components::CCMHome::_nil ()); + } + + //Note: If the return value will be discarded, it must be kept in a var or + // release () will have to be called explicitly. + return newhome._retn (); +} + + +void +CIAO::Container_Impl::remove_home (const char * comp_ins_name) + ACE_THROW_SPEC ((CORBA::SystemException, + Components::RemoveFailure)) +{ + CIAO_TRACE ("CIAO::Container_Impl::remove_home"); + + Components::CCMHome_ptr home; + ACE_CString str (comp_ins_name); + + if (this->home_map_.find (str, home) != 0) + throw CORBA::BAD_PARAM (); + + // @@TODO We should remove all components created by this home as well. + // This is not implemented yet. + + this->container_->ciao_uninstall_home (home); + + // If the previous calls failed, what should we do here?? + CORBA::release (home); + + // @@ Still need to remove the home if the previous operation fails? + if (this->home_map_.unbind (str) == -1) + throw ::Components::RemoveFailure (); +} + +// Remove all homes and components +void +CIAO::Container_Impl::remove () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::RemoveFailure)) +{ + CIAO_TRACE ("CIAO::Container_Impl::remove"); + + // Remove all components first. + this->remove_components (); + + // Even if above operation failed we should still remove homes. + const Home_Iterator end = this->home_map_.end (); + for (Home_Iterator iter (this->home_map_.begin ()); + iter != end; + ++iter) + { + this->container_->ciao_uninstall_home ( (*iter).int_id_); + + CORBA::release ( (*iter).int_id_); + } + + this->home_map_.unbind_all (); + + if (CIAO::debug_level () > 3) + ACE_DEBUG ((LM_DEBUG, + "Removed all homes and components from this container!\n")); +} + +//////////////////////////////////////////////////////////////////////// +// Internal helper functions. +//////////////////////////////////////////////////////////////////////// + +void +CIAO::Container_Impl::remove_components () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::RemoveFailure)) +{ + CIAO_TRACE ("CIAO::Container_Impl::remove_components"); + + // Remove all the components in the NodeApplication/Container + // Release all component servant object. + const Component_Iterator end = this->component_map_.end (); + for (Component_Iterator iter (this->component_map_.begin ()); + iter != end; + ++iter) + { + // Find the component home first, then call the remove_component + // on the home. + Components::CCMHome_ptr home; + if (this->home_map_.find ( (*iter).ext_id_, home) != 0) + throw CORBA::BAD_PARAM (); + + // This will call ccm_passivate on the component executor. + home->remove_component (((*iter).int_id_).in ()); + + //CORBA::release (((*iter).int_id_).in ()); + } + + this->component_map_.unbind_all (); + // To this point the servant should have been destroyed. However, + // if someone is still making calls on the servant, terrible thing + // will happen. +} + + +// Below method is not used actually. +void +CIAO::Container_Impl::remove_component (const char * comp_ins_name) + ACE_THROW_SPEC ((CORBA::SystemException, + Components::RemoveFailure)) +{ + CIAO_TRACE ("CIAO::Container_Impl::remove_component"); + + Components::CCMObject_var comp; + Components::CCMHome_ptr home; + + ACE_CString naming_context; + + ACE_CString str (comp_ins_name); + + if (CIAO::debug_level () > 5) + ACE_DEBUG ((LM_DEBUG, "CIAO::COntainer_Impl::remove_component: Removing comp_ins_name:: %s\n", + str.c_str ())); + + /* Before we do remove component we have to inform the homeservant so + * Component::ccm_passivate () + * constainer::uninstall_component () ->deactivate_object () will be called. + * + * ccm_remove will be called when the poa destroys the servant. + */ + + if (this->component_map_.find (str, comp) != 0) + throw CORBA::BAD_PARAM (); + + if (this->home_map_.find (str, home) != 0) + throw CORBA::BAD_PARAM (); + + // This will call ccm_passivate on the component executor. + home->remove_component (comp.in ()); + + // If the previous calls failed, what should we do here?? + + // @@ Still need to remove the home if the previous operation fails? + if (this->component_map_.unbind (str) == -1) + throw ::Components::RemoveFailure (); + + if (this->naming_map_.find (str, naming_context) == 0) + { + + bool const result = + unregister_with_ns ( + naming_context.c_str (), + this->orb_.in () + ); + + if (!result) + { + ACE_DEBUG ((LM_DEBUG, + "Failed to unregister with naming service.\n")); + } + else + { + if (this->naming_map_.unbind (str) == -1) + throw ::Components::RemoveFailure (); + } + } +} + +bool +CIAO::Container_Impl::register_with_ns (const char * s, + CORBA::ORB_ptr orb, + Components::CCMObject_ptr obj) +{ + CIAO_TRACE ("CIAO::Container_Impl::register_with_ns"); + + try + { + // Obtain the naming service + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService"); + + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + "DAnCE: (%P|%t) Unable to get the Naming Service.\n"), + false); + + CosNaming::NamingContextExt_var root = + CosNaming::NamingContextExt::_narrow (naming_obj.in ()); + + CosNaming::Name name (0); + name.length (0); + + // Get the multicomponent naming context from the <naming_context>. + // The convention of this <naming_context> input string is that + // different naming context is separated by character '/', such as + // "create a naming context A/B/C/D". + ACE_CString tmp (s); + char * naming_string = tmp.rep (); + char seps[] = "/:"; + + char *token, *lastToken = 0; + token = ACE_OS::strtok (naming_string, seps); + + for (CORBA::ULong i = 0; token != 0; ++i) + { + // While there still are tokens in the "naming_string" + name.length (name.length () + 1); + name[i].id = CORBA::string_dup (token); + + // Get next naming context + lastToken = token; + token = ACE_OS::strtok ( 0, seps ); + } + + if (name.length() > 1) + { + // Let's create the context path first + name.length(name.length()-1); + Utility::NameUtility::CreateContextPath (root.in (), name); + name.length(name.length()+1); + name[name.length()-1].id = CORBA::string_dup(lastToken); + } + + // Bind the actual object + Utility::NameUtility::BindObjectPath (root.in (), name, obj); + + return true; + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("CIAO (%P|%t) Container_Impl.cpp -" + "CIAO::Container_Impl::register_with_ns -" + "NodeApplication: failed to register " + "with naming service."); + return false; + } + return true; +} + +bool +CIAO::Container_Impl::unregister_with_ns (const char * obj_name, + CORBA::ORB_ptr orb) +{ + CIAO_TRACE ("CIAO::Container_Impl::unregister_with_ns"); + + try + { + // Obtain the naming service + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService"); + + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the Naming Service.\n"), + false); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in ()); + + CosNaming::Name name (0); + name.length (0); + + // Get the multicomponent naming context from the <naming_context>. + // The convention of this <naming_context> input string is that + // different naming context is separated by character '/', such as + // "create a naming context A/B/C/D". + ACE_CString tmp (obj_name); + char * naming_string = tmp.rep (); + char seps[] = "/:"; + + char *token, *lastToken = 0; + token = ACE_OS::strtok (naming_string, seps); + + for (CORBA::ULong i = 0; token != 0; ++i) + { + // While there still are tokens in the "naming_string" + name.length (name.length () + 1); + name[i].id = CORBA::string_dup (token); + + // Get next naming context + lastToken = token; + token = ACE_OS::strtok ( 0, seps ); + } + + // Unregister with the Name Server + ACE_DEBUG ((LM_DEBUG, + "Unregister component with the name server : %s!\n", + obj_name)); + naming_context->unbind (name); + + return true; + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("CIAO (%P|%t) Container_Impl.cpp -" + "CIAO::Container_Impl::unregister_with_ns -" + "NodeApplication: failed to unregister " + "with naming service."); + return false; + } + return true; +} diff --git a/modules/CIAO/DAnCE/NodeApplication/Container_Impl.h b/modules/CIAO/DAnCE/NodeApplication/Container_Impl.h new file mode 100644 index 00000000000..7becc7b8e9e --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/Container_Impl.h @@ -0,0 +1,215 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file Container_Impl.h + * + * $Id$ + * + * This file contains implementation for the servant of + * Components::Deployment::Container interface. + * + * @author Nanbor Wang <nanbor@cs.wustl.edu> + * @author Gan Deng <gan.deng@vanderbilt.edu> + */ +//============================================================================= + + +#ifndef CIAO_CONTAINER_IMPL_H +#define CIAO_CONTAINER_IMPL_H +#include /**/ "ace/pre.h" + +#include "CIAO_NodeApplication_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ciao/Deployment_ContainerS.h" +#include "ciao/Deployment_NodeApplicationC.h" +#include "ciao/Container_Base.h" +#include "ace/SString.h" +#include "ciao/Server_init.h" // write_IOR function & NameUtility +#include "ciao/CIAO_common.h" // CIAO::debug_level + +namespace CIAO +{ + /** + * @class Container_Impl + * + * @brief Servant implementation for the interface Deployment::Container + * + * This class implements the Deployment::Container + * interface which is not defined by the CCM DnC specification. + * As the interface implies, this is actually part of the deployment + * interface and is used to manage the lifecycle of the installed + * components and homes. + */ + class NODEAPPLICATION_Export Container_Impl + : public virtual POA_Deployment::Container + { + public: + /// Constructor + Container_Impl (CORBA::ORB_ptr o, + PortableServer::POA_ptr p, + ::Deployment::NodeApplication_ptr server, + const Static_Config_EntryPoints_Maps* static_entrypts_maps =0); + + /// Destructor + virtual ~Container_Impl (void); + + /*-------------------------------------------------------------*/ + /*-------------------- IDL operations (idl) ------------------*/ + + /// Initialize the container. + virtual CORBA::Long init (const CORBA::PolicyList *policies) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Install all homes and components + Deployment::ComponentInfos * + install (const ::Deployment::ContainerImplementationInfo & container_impl_info) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::UnknownImplId, + Deployment::ImplEntryPointNotFound, + Deployment::InstallationFailure, + Components::InvalidConfiguration)); + + /// Remove all homes and components + virtual void + remove () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::RemoveFailure)); + + /// Deployment::Container interface defined attributes/operations. + virtual ::Deployment::Properties * + properties () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::Deployment::NodeApplication_ptr + get_node_application () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /*-------------------------------------------------------------*/ + /*------------------- C++ help methods (c++) -----------------*/ + + /// Get the containing POA. This operation does *not* + /// increase the reference count of the POA. + virtual PortableServer::POA_ptr _default_POA (void); + + + // Install the home of this particular component + virtual ::Components::CCMHome_ptr + install_home (const ::Deployment::ComponentImplementationInfo & impl_info) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::UnknownImplId, + Deployment::ImplEntryPointNotFound, + Deployment::InstallationFailure, + Components::InvalidConfiguration)); + + /** + * @@Note: I don't know how to remove a home right now. + * I assume that user will only call remove instead. + * This is true at least for DnC run time. + * + * Right now, in this implementation I assumpe that there will be + * same number of homes as the components even if the components + * are of the same type. I don't think that we have the modeling + * side support of this either. So bear me if you think I avoid + * the real thinking for easiness. + */ + // Remove the home of this particular component + virtual void + remove_home (const char * comp_ins_name) + ACE_THROW_SPEC ((CORBA::SystemException, + Components::RemoveFailure)); + + bool + register_with_ns (const char * obj_name, + CORBA::ORB_ptr orb, + Components::CCMObject_ptr obj); + + bool + unregister_with_ns (const char * obj_name, + CORBA::ORB_ptr orb); + + + // ------------------- CIAO Internal Operations ------------------------ + // These below two are helper methods to clean up components + // should only be called when we are sure that there is no + // active connection on this component. + virtual void remove_components () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::RemoveFailure)); + + virtual void remove_component (const char * comp_ins_name) + ACE_THROW_SPEC ((CORBA::SystemException, + Components::RemoveFailure)); + + /// Set the cached object reference. + void set_objref (Deployment::Container_ptr o); + + /// Get the cached object reference. This operation will invoke + /// _this if there's no cached reference available. Notice that + /// this method does *NOT* increase the reference count of the + /// cached reference. + /// @@ Gan, caller should own memory. In this case you shoudl + /// return a duplicate OR add a const to the operation + /// signature. This is simply bad programming. + Deployment::Container_ptr get_objref (); + +protected: + /// Keep a pointer to the managing ORB serving this servant. + CORBA::ORB_var orb_; + + /// Keep a pointer to the managing POA. + PortableServer::POA_var poa_; + + /// Internal container implementation. + // @@ Gan/Jai, heard of auto_ptr <>? + CIAO::Container *container_; + + /// Cached ConfigValues. + Deployment::Properties properties_; + + /// Cached Container reference (of ourselves.) + Deployment::Container_var objref_; + + /// Cached NodeApplication. + Deployment::NodeApplication_var nodeapp_; + + /// To store all created CCMHome object + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + Components::CCMHome_ptr, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> CCMHome_Map; + typedef CCMHome_Map::iterator Home_Iterator; + CCMHome_Map home_map_; + + /// To store all created Component object. + // @@Gan, see how this caching is duplicated.. + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + Components::CCMObject_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> CCMComponent_Map; + typedef CCMComponent_Map::iterator Component_Iterator; + CCMComponent_Map component_map_; + + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + ACE_CString, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> CCMNaming_Map; + CCMNaming_Map naming_map_; + + const Static_Config_EntryPoints_Maps* static_entrypts_maps_; + }; +} + +#if defined (__ACE_INLINE__) +# include "Container_Impl.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* CIAO_CONTAINER_IMPL_H */ diff --git a/modules/CIAO/DAnCE/NodeApplication/Container_Impl.inl b/modules/CIAO/DAnCE/NodeApplication/Container_Impl.inl new file mode 100644 index 00000000000..85c17197070 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/Container_Impl.inl @@ -0,0 +1,37 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +CIAO::Container_Impl::Container_Impl (CORBA::ORB_ptr o, + PortableServer::POA_ptr p, + ::Deployment::NodeApplication_ptr server, + const Static_Config_EntryPoints_Maps* static_entrypts_maps) + : orb_ (CORBA::ORB::_duplicate (o)), + poa_ (PortableServer::POA::_duplicate (p)), + nodeapp_ (::Deployment::NodeApplication::_duplicate (server)), + static_entrypts_maps_ (static_entrypts_maps) +{ +} + +ACE_INLINE void +CIAO::Container_Impl::set_objref (Deployment::Container_ptr o) +{ + CIAO_TRACE("CIAO::Container_Imp::set_objref"); + + if (!CORBA::is_nil (this->objref_.in ())) + throw CORBA::BAD_INV_ORDER (); + + this->objref_ = Deployment::Container::_duplicate (o); +} + +ACE_INLINE ::Deployment::Container_ptr +CIAO::Container_Impl::get_objref () +{ + CIAO_TRACE("CIAO::Container_Imp::get_objref"); + + if (CORBA::is_nil (this->objref_.in ())) + { + this->objref_ = this->_this (); + } + return this->objref_.in (); +} diff --git a/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator.cpp b/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator.cpp new file mode 100644 index 00000000000..4ffe48cd7d2 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator.cpp @@ -0,0 +1,39 @@ +// $Id$ + +#include "NoOp_Configurator.h" + +CIAO::NoOp_Configurator::~NoOp_Configurator (void) +{ + // Not much to do. +} + +int +CIAO::NoOp_Configurator::pre_orb_initialize () +{ + return 0; +} + +int +CIAO::NoOp_Configurator::post_orb_initialize (CORBA::ORB_ptr) +{ + return 0; +} + +int +CIAO::NoOp_Configurator::init_resource_manager +(const ::Deployment::Properties & /*properties*/) +{ + // @@ Currently do thing. We should go over the resource struct in + // the future and throw exceptions if there are + // un-recognizable/supported stuff in it. + return 0; +} + +CORBA::PolicyList * +CIAO::NoOp_Configurator::find_container_policies +(const ::Deployment::Properties & /*properties*/) +{ + // Not much to do. + + return 0; +} diff --git a/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator.h b/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator.h new file mode 100644 index 00000000000..6c32b83ce0d --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator.h @@ -0,0 +1,62 @@ +/** $Id$ + * @file NoOp_Configurator.h + * @brief This file contains the noop configurator. + */ + +#ifndef NOOP_CONFIGURATOR_H +#define NOOP_CONFIGURATOR_H + +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "NodeApp_Configurator.h" +#include "NoOp_Configurator_export.h" + +namespace CIAO +{ + /** + * @class NoOP_Configurator + * + * @brief The NoOp_Configurator doesn't do anything. + */ + class NoOp_Configurator_Export NoOp_Configurator + : public NodeApp_Configurator + { + public: + /// Default destructor. + virtual ~NoOp_Configurator (void); + + /** + * @brief "pre_orb_initialize" is called before ORB_init. + */ + virtual int pre_orb_initialize (void); + + /** + * @brief "post_orb_initialize" is called after NodeApplication + * get a hold at this object. + */ + virtual int post_orb_initialize (CORBA::ORB_ptr o); + + /** + * @brief "init_resource_manager" is called by NodeApplication when + * it receives an "install" commands. + */ + virtual int + init_resource_manager (const ::Deployment::Properties &properties); + + /** + * @brief get a policyset by its name. + */ + virtual CORBA::PolicyList * + find_container_policies (const ::Deployment::Properties &properties); + }; + +} + +#include /**/ "ace/post.h" +#endif /* NOOP_CONFIGURATOR_H */ diff --git a/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator_export.h b/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator_export.h new file mode 100644 index 00000000000..dce4b728146 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NoOp_Configurator_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl NoOp_Configurator +// ------------------------------ +#ifndef NOOP_CONFIGURATOR_EXPORT_H +#define NOOP_CONFIGURATOR_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (NOOP_CONFIGURATOR_HAS_DLL) +# define NOOP_CONFIGURATOR_HAS_DLL 1 +#endif /* ! NOOP_CONFIGURATOR_HAS_DLL */ + +#if defined (NOOP_CONFIGURATOR_HAS_DLL) && (NOOP_CONFIGURATOR_HAS_DLL == 1) +# if defined (NOOP_CONFIGURATOR_BUILD_DLL) +# define NoOp_Configurator_Export ACE_Proper_Export_Flag +# define NOOP_CONFIGURATOR_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define NOOP_CONFIGURATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* NOOP_CONFIGURATOR_BUILD_DLL */ +# define NoOp_Configurator_Export ACE_Proper_Import_Flag +# define NOOP_CONFIGURATOR_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define NOOP_CONFIGURATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* NOOP_CONFIGURATOR_BUILD_DLL */ +#else /* NOOP_CONFIGURATOR_HAS_DLL == 1 */ +# define NoOp_Configurator_Export +# define NOOP_CONFIGURATOR_SINGLETON_DECLARATION(T) +# define NOOP_CONFIGURATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* NOOP_CONFIGURATOR_HAS_DLL == 1 */ + +// Set NOOP_CONFIGURATOR_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (NOOP_CONFIGURATOR_NTRACE) +# if (ACE_NTRACE == 1) +# define NOOP_CONFIGURATOR_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define NOOP_CONFIGURATOR_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !NOOP_CONFIGURATOR_NTRACE */ + +#if (NOOP_CONFIGURATOR_NTRACE == 1) +# define NOOP_CONFIGURATOR_TRACE(X) +#else /* (NOOP_CONFIGURATOR_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define NOOP_CONFIGURATOR_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (NOOP_CONFIGURATOR_NTRACE == 1) */ + +#endif /* NOOP_CONFIGURATOR_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApp_Configurator.h b/modules/CIAO/DAnCE/NodeApplication/NodeApp_Configurator.h new file mode 100644 index 00000000000..b3eb92b4482 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApp_Configurator.h @@ -0,0 +1,90 @@ +//$Id$ +/**======================================================== + * + * @file NodeApp_Configurator.h + * + * @Brief This file contains the implementation of + * the basic NodeApp_Configurator interface, the one + * that does nothing more + * + * @author Nanbor Wang <nanbor@exothermic.txcorp.com> + *========================================================*/ + +#ifndef NODEAPP_CONFIGURATOR_H +#define NODEAPP_CONFIGURATOR_H +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ciao/Deployment_CoreC.h" + +namespace CIAO +{ + /** + * + * @class NodeApp_Configurator + * + * @brief This class defines and implements the default + * NodeApp_Configurator base class that's needed for configuring the + * NodeApplication process. + **/ + class NodeApp_Configurator + { + public: + /// Default destructor. + virtual ~NodeApp_Configurator (void) {} + + /** + * @brief "pre_orb_initialize" is called before ORB_init. + */ + virtual int pre_orb_initialize (void) = 0; + + /** + * @brief "post_orb_initialize" is called after NodeApplication + * get a hold at this object. + */ + virtual int post_orb_initialize (CORBA::ORB_ptr o) = 0; + + /** + * @brief "init_resource_manager" is called by NodeApplication when + * it receives an "install" commands. + */ + virtual int + init_resource_manager (const ::Deployment::Properties &properties) = 0; + + /** + * @brief get a policyset by its name. + */ + virtual CORBA::PolicyList * + find_container_policies (const ::Deployment::Properties &properties) = 0; + + /// @@ Perhaps we also need a finalizer method here. Perhaps we + /// even need to differentiate finalizer before ORB is destroyed + /// and the one after that. + }; +} + +/** + * For dynamically linkable concrete NodeApp_Configurator + * implementation, remember to create a factory method using "C" + * calling convention in the CPP file as follow: + + extern "C" EXPORT_MACRO CIAO::NodeApp_Configurator *create_nodeapp_configurator (void); + + CIAO::NodeApp_Configurator * + create_nodeapp_configurator (void) + { + concrete_NodeApp_Configurator *config; + ACE_NEW_RETURN (config, concrete_NodeApp_Configurator, 0); + return config; + } + + */ + + +#include /**/ "ace/post.h" +#endif /* NODEAPP_CONFIGURATOR_H */ diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApplication.cpp b/modules/CIAO/DAnCE/NodeApplication/NodeApplication.cpp new file mode 100644 index 00000000000..021f1e5322c --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApplication.cpp @@ -0,0 +1,52 @@ +// $Id$ + +#include "NodeApplication_Core.h" +#include "ace/Sched_Params.h" +#include "ace/OS_NS_errno.h" +#include "ciao/CIAO_common.h" + +#include <orbsvcs/Event/EC_Default_Factory.h> + +void print_arg (int argc, char *argv[]) +{ + for (int i = 0; i < argc; ++i) + ACE_DEBUG ((LM_DEBUG, "NodeApplication ARGV[%d] = %s\n", i, argv [i])); +} + +int +main (int argc, char *argv[]) +{ + try + { + TAO_EC_Default_Factory::init_svcs (); + + ACE_DEBUG ((LM_DEBUG, "*** Starting NodeApplication\n")); + + CIAO::NodeApplication_Options nodeapp_options; + + if (CIAO::debug_level () > 9) + print_arg (argc, argv); + + if (nodeapp_options.parse_args (argc, argv) != 0) + return -1; + + CIAO::NodeApplication_Core nodeapp_core (nodeapp_options); + + if (nodeapp_core.startup (argc, argv) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Unable to start up the NodeApplication_Core\n"), -1); + + // Run the main event loop for the ORB. + nodeapp_core.run_orb (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("NodeApp::main\t\n"); + return 1; + } + + if (CIAO::debug_level () > 1) + ACE_DEBUG ((LM_DEBUG, "CIAO (%P|%t) - This NodeApplication is destroyed!\n")); + + return 0; +} diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApplication.mpc b/modules/CIAO/DAnCE/NodeApplication/NodeApplication.mpc new file mode 100644 index 00000000000..a801e308c5c --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApplication.mpc @@ -0,0 +1,41 @@ +// -*- MPC -*- +// $Id$ + +project(NoOp_Configurator): ciao_deployment_stub { + sharedname = CIAO_NoOp_Configurator + dynamicflags = NOOP_CONFIGURATOR_BUILD_DLL + + Source_Files { + NoOp_Configurator.cpp + } +} + +project(NodeApplicationLib): ciao_server_dnc, ciao_events_dnc, ciao_noop_configurator { + sharedname = CIAO_NodeApplication + dynamicflags = NODEAPPLICATION_BUILD_DLL + + Source_Files { + Configurator_Factory.cpp + Container_Impl.cpp + NodeApplication_Core.cpp + NodeApplication_Impl.cpp + } +} + +project(NodeApplication): ciao_server_dnc, ciao_events_dnc, ciao_nodeapplication, ciao_noop_configurator { + exename = NodeApplication + + Source_Files { + NodeApplication.cpp + } +} + +project(RTNA_Configurator): ciao_deployment_stub, rt_server { + sharedname = CIAO_RTNA_Configurator + dynamicflags = CIAO_RTNA_CONFIGURATOR_BUILD_DLL + + Source_Files { + RTNodeApp_Configurator.cpp + RTConfig_Manager.cpp + } +} diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.cpp b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.cpp new file mode 100644 index 00000000000..eef577b2cfd --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.cpp @@ -0,0 +1,252 @@ +// $Id$ + +#include "ciao/CIAO_NodeApplication_CallBackC.h" +#include "ace/Sched_Params.h" +#include "NodeApplication_Impl.h" +#include "NodeApplication_Core.h" +#include "ace/Null_Mutex.h" +#include "ciao/Server_init.h" +#include "ciao/CIAO_common.h" + +#if !defined (__ACE_INLINE__) +# include "NodeApplication_Core.inl" +#endif /* __ACE_INLINE__ */ + +const char * +sched_policy_name (int sched_policy) +{ + const char *name = 0; + + switch (sched_policy) + { + case ACE_SCHED_OTHER: + name = "SCHED_OTHER"; + break; + case ACE_SCHED_RR: + name = "SCHED_RR"; + break; + case ACE_SCHED_FIFO: + name = "SCHED_FIFO"; + break; + } + + return name; +} + + +/// The following check is taken from $(TAO_ROOT)/tests/RTCORBA/ +int +check_supported_priorities (CORBA::ORB_ptr orb) +{ + CIAO_TRACE ("NodeApplication_Core::check_supported_priorities"); + + int const sched_policy = + orb->orb_core ()->orb_params ()->ace_sched_policy (); + + // Check that we have sufficient priority range to run, + // i.e., more than 1 priority level. + int const max_priority = + ACE_Sched_Params::priority_max (sched_policy); + int const min_priority = + ACE_Sched_Params::priority_min (sched_policy); + + if (max_priority == min_priority) + { + ACE_DEBUG ((LM_DEBUG, + "Not enough priority levels with the %s scheduling policy\n" + "on this platform to run, terminating program....\n" + "Check svc.conf options\n", + sched_policy_name (sched_policy))); + + return -1; + } + return 0; +} + +int +CIAO::NodeApplication_Core::svc () +{ + CIAO_TRACE ("CIAO::NodeApplication_Core::svc"); + + try + { + CORBA::Object_var object = + this->orb_->resolve_initial_references ("RootPOA"); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (object.in ()); + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (); + + poa_manager->activate (); + + // ... + CIAO::NodeApplication_Impl *nodeapp_servant = 0; + + ACE_NEW_RETURN (nodeapp_servant, + CIAO::NodeApplication_Impl (this->orb_.in (), + root_poa.in (), + *this->configurator_.get ()), + -1); + + PortableServer::ServantBase_var safe_servant (nodeapp_servant); + + // Configuring NodeApplication. + PortableServer::ObjectId_var nodeapp_oid + = root_poa->activate_object (nodeapp_servant); + + object = root_poa->id_to_reference (nodeapp_oid.in ()); + + Deployment::NodeApplication_var nodeapp_obj = + Deployment::NodeApplication::_narrow (object.in ()); + + if (CORBA::is_nil (nodeapp_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + "Unable to activate NodeApplication object\n"), + -1); + + /** @@ We need to call NodeApplication servant's init method. + * But it's not sure to me where exactly we can get the + * Properties needed by the init method at this moment. There are two + * ways to set the property of the NodeApplication: + * 1. call init remotely from NodeApplicationManager + * 2. call init locally on the servant of NodeApplication. + */ + bool retval = nodeapp_servant->init (); + + if (retval) + { + ACE_DEBUG ((LM_DEBUG, "NodeApplication Failed on creating and\ + initializing the session container!")); + return 1; + } + + CORBA::String_var str = this->orb_->object_to_string (nodeapp_obj.in ()); + + if (this->options_.write_ior_file ()) + CIAO::Utility::write_IOR (this->options_.ior_output_filename (), + str.in ()); + + // End Deployment part + if (CIAO::debug_level () > 10) + { + ACE_DEBUG ((LM_INFO, "NodeApplication IOR: %s\n", str.in ())); + + } + + Deployment::NodeApplicationManager_var nodeapp_man; + Deployment::Properties_var prop = new Deployment::Properties; + + if (this->options_.use_callback ()) + { + object = this->orb_->string_to_object (this->options_.callback_ior ()); + + CIAO::NodeApplication_Callback_var nam_callback + = CIAO::NodeApplication_Callback::_narrow (object.in ()); + + Deployment::Properties_out properties_out (prop.out ()); + + nodeapp_man + = nam_callback->register_node_application (nodeapp_obj.in (), + properties_out); + } + + ACE_DEBUG ((LM_DEBUG, + "Running NodeApplication...\n")); + + this->orb_->run (); + + root_poa->destroy (1, 1); + + this->orb_->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught"); + return -1; + } + + ACE_DEBUG ((LM_DEBUG, + "Exiting NodeApplication...\n")); + return 0; +} + +int +CIAO::NodeApplication_Core::startup (int argc, char *argv[]) +{ + CIAO_TRACE ("CIAO::NodeApplication_Core::startup"); + + // pre-init + this->configurator_.reset (this->options_.create_nodeapp_configurator ()); + + if (this->configurator_->pre_orb_initialize ()) + return -1; + + // Initialize orb + this->orb_ = + CORBA::ORB_init (argc, + argv, + ""); + CIAO::Server_init (this->orb_.in ()); + + return this->configurator_->post_orb_initialize (this->orb_.in ()); +} + +int +CIAO::NodeApplication_Core::run_orb () +{ + CIAO_TRACE ("CIAO::NodeApplication_Core::run_orb"); + + // check supported priority before running RT + if (this->options_.rt_support () && + check_supported_priorities (this->orb_.in ()) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, "ERROR: DISABLE RT SUPPORT\n"), -1); + // this->options_.rt_support_ = 0; + } + + if (this->options_.rt_support ()) // RT support reuqested + { + + + // spawn a thread + // Task activation flags. + long flags = + THR_NEW_LWP | + THR_JOINABLE | + this->orb_->orb_core ()->orb_params ()->thread_creation_flags (); + + // Activate task. + int result = + this->activate (flags); + if (result == -1) + { + if (errno == EPERM) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot create thread with scheduling policy %s\n" + "because the user does not have the appropriate privileges, terminating program....\n" + "Check svc.conf options and/or run as root\n", + sched_policy_name (this->orb_->orb_core ()->orb_params ()->ace_sched_policy ())), + 2); + } + else + return -1; + } + + ACE_DEBUG ((LM_DEBUG, "*** Running NodeApplication in RT mode\n")); + + // Wait for task to exit. + result = + this->wait (); + ACE_ASSERT (result != -1); + + ACE_DEBUG ((LM_INFO, "*** Ending NodeApplication\n")); + return 0; + + } + else + return this->svc (); +} + diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.h b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.h new file mode 100644 index 00000000000..aceef49209c --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.h @@ -0,0 +1,70 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file NodeApplication_Core.h + * + * $Id$ + * + * An ACE_Task subclass that manages the NodeApplication runtime. We + * can run this class as a separate thread, as in the case of RT + * support, or as a event driven ORB. + * + * @author Nanbor Wang <nanbor@cs.wustl.edu> + */ +//============================================================================= + + +#ifndef CIAO_NODEAPPLICATION_CORE_H +#define CIAO_NODEAPPLICATION_CORE_H +#include /**/ "ace/pre.h" + +#include "CIAO_NodeApplication_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/ORB_Core.h" +#include "tao/ORB.h" +#include "ace/Task.h" +#include "ace/Auto_Ptr.h" +#include "Configurator_Factory.h" +#include "NoOp_Configurator.h" + +namespace CIAO +{ + /** + * @class NodeApplication_Core + * + * @brief An ACE_Task subclass that allow the ORB thread to be run + * as separate thread when RT behaviors are needed. + */ + class NODEAPPLICATION_Export NodeApplication_Core + : public virtual ACE_Task_Base + { + public: + NodeApplication_Core (NodeApplication_Options &opts); + + virtual int svc (void); + + int startup (int argc, char *argv[]); + + int run_orb (void); + + protected: + CORBA::ORB_var orb_; + + NodeApplication_Options &options_; + + auto_ptr<NodeApp_Configurator> configurator_; + }; + +} + +#if defined (__ACE_INLINE__) +# include "NodeApplication_Core.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* CIAO_NODEAPPLICAITON_CORE_H */ diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.inl b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.inl new file mode 100644 index 00000000000..f1f1e82da0c --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Core.inl @@ -0,0 +1,9 @@ +// -*- C++ -*- +// $Id$ + +ACE_INLINE +CIAO::NodeApplication_Core::NodeApplication_Core (CIAO::NodeApplication_Options &opts) + : options_ (opts) +{ +} + diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.cpp b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.cpp new file mode 100644 index 00000000000..afbb5c9bcc6 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.cpp @@ -0,0 +1,1256 @@ +// $Id$ + +#include "NodeApplication_Impl.h" +#include "ace/SString.h" +#include "Container_Impl.h" +#include "Deployment_EventsC.h" +#include "ciaosvcs/Events/CIAO_RTEC/CIAO_RTEventC.h" + +#if !defined (__ACE_INLINE__) +# include "NodeApplication_Impl.inl" +#endif /* __ACE_INLINE__ */ + +CIAO::NodeApplication_Impl::~NodeApplication_Impl (void) +{ +} + + +CORBA::Long +CIAO::NodeApplication_Impl::init () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + /// @todo initialize this NodeApplication properties + return 0; +} + +CORBA::Long +CIAO::NodeApplication_Impl::create_all_containers ( + const ::Deployment::ContainerImplementationInfos & container_infos + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Create all the containers here based on the input node_impl_info. + CORBA::ULong const len = container_infos.length (); + + for (CORBA::ULong i = 0; i < len; ++i) + { + // The factory method <create_container> will intialize the container + // servant with properties, so we don't need to call <init> on the + // container object reference. + // Also, the factory method will add the container object reference + // to the set for us. + ::Deployment::Container_var cref = + this->create_container (container_infos[i].container_config); + + // Build the Component_Container_Map + for (CORBA::ULong j = 0; + j < container_infos[i].impl_infos.length (); + ++j) + { + this->component_container_map_.bind ( + container_infos[i].impl_infos[j].component_instance_name.in (), + ::Deployment::Container::_duplicate (cref.in ())); + } + } + + return 0; +} + +void +CIAO::NodeApplication_Impl::finishLaunch ( + const Deployment::Connections & providedReference, + CORBA::Boolean start, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError, + Deployment::InvalidConnection)) +{ + ACE_UNUSED_ARG (start); + + // If parameter "add_connection" is true, then it means we want to "add" + // new connections, other, we remove existing connections + this->finishLaunch_i (providedReference, start, add_connection); +} + +void +CIAO::NodeApplication_Impl::finishLaunch_i ( + const Deployment::Connections & connections, + CORBA::Boolean start, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError, + Deployment::InvalidConnection)) +{ + ACE_UNUSED_ARG (start); + + try + { + CORBA::ULong const length = connections.length (); + + // For every connection struct we finish the connection. + for (CORBA::ULong i = 0; i < length; ++i) + { + ACE_CString name = connections[i].instanceName.in (); + + // For ES_to_Consumer connection, we simply call + // handle_es_consumer_connection method. + //if (connections[i].kind == Deployment::rtecEventConsumer) + if (this->_is_es_consumer_conn (connections[i])) + { + this->handle_es_consumer_connection ( + connections[i], + add_connection); + continue; + } + + // For other type of connections, we need to fetch the + // objref of the source component + Component_State_Info comp_state; + + if (this->component_state_map_.find (name, comp_state) != 0) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::finishLaunch, " + "invalid port name [%s] in instance [%s] \n", + connections[i].portName.in (), + name.c_str ())); + throw Deployment::InvalidConnection (); + } + + Components::EventConsumerBase_var consumer; + + Components::CCMObject_var comp = comp_state.objref_; + + if (CORBA::is_nil (comp.in ())) + { + ACE_DEBUG ((LM_DEBUG, "comp is nil\n")); + throw Deployment::InvalidConnection (); + } + + switch (connections[i].kind) + { + case Deployment::SimplexReceptacle: + case Deployment::MultiplexReceptacle: + this->handle_facet_receptable_connection ( + comp.in (), + connections[i], + add_connection); + break; + + case Deployment::EventEmitter: + this->handle_emitter_consumer_connection ( + comp.in (), + connections[i], + add_connection); + break; + + case Deployment::EventPublisher: + if (this->_is_publisher_es_conn (connections[i])) + this->handle_publisher_es_connection ( + comp.in (), + connections[i], + add_connection); + else + this->handle_publisher_consumer_connection ( + comp.in (), + connections[i], + add_connection); + break; + + default: + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::finishLaunch_i: " + "Unsupported event port type encounted\n")); + throw CORBA::NO_IMPLEMENT (); + } + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("NodeApplication_Impl::finishLaunch\t\n"); + throw; + } + +} + +void +CIAO::NodeApplication_Impl::ciao_preactivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + Component_Iterator end = this->component_state_map_.end (); + for (Component_Iterator iter (this->component_state_map_.begin ()); + iter != end; + ++iter) + { + if (((*iter).int_id_).state_ == NEW_BORN) + { + ((*iter).int_id_).objref_->ciao_preactivate (); + } + + ((*iter).int_id_).state_ = PRE_ACTIVE; + } +} + +void +CIAO::NodeApplication_Impl::start () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + Component_Iterator end = this->component_state_map_.end (); + for (Component_Iterator iter (this->component_state_map_.begin ()); + iter != end; + ++iter) + { + if (((*iter).int_id_).state_ == PRE_ACTIVE) + { + ((*iter).int_id_).objref_->ciao_activate (); + } + + ((*iter).int_id_).state_ = ACTIVE; + } +} + +void +CIAO::NodeApplication_Impl::ciao_postactivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)) +{ + Component_Iterator end = this->component_state_map_.end (); + for (Component_Iterator iter (this->component_state_map_.begin ()); + iter != end; + ++iter) + { + if (((*iter).int_id_).state_ == ACTIVE) + { + ((*iter).int_id_).objref_->ciao_postactivate (); + + ((*iter).int_id_).state_ = POST_ACTIVE; + } + } +} + +void +CIAO::NodeApplication_Impl::ciao_passivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)) +{ + Component_Iterator end = this->component_state_map_.end (); + for (Component_Iterator iter (this->component_state_map_.begin ()); + iter != end; + ++iter) + { + ((*iter).int_id_).objref_->ciao_passivate (); + + ((*iter).int_id_).state_ = PASSIVE; + } + ACE_DEBUG ((LM_DEBUG, "exiting passivate\n")); +} + +Deployment::ComponentInfos * +CIAO::NodeApplication_Impl::install ( + const ::Deployment::NodeImplementationInfo & node_impl_info) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::UnknownImplId, + Deployment::ImplEntryPointNotFound, + Deployment::InstallationFailure, + Components::InvalidConfiguration)) +{ + Deployment::ComponentInfos_var retv; + try + { + // Extract ORB resource def here. + this->configurator_.init_resource_manager (node_impl_info.nodeapp_config); + + const ::Deployment::ContainerImplementationInfos container_infos = + node_impl_info.impl_infos; + + ACE_NEW_THROW_EX (retv, + Deployment::ComponentInfos, + CORBA::NO_MEMORY ()); + + retv->length (0UL); + + // Call create_all_containers to create all the necessary containers.. + // @@(GD): The "create_all_containers" mechanism needs to be refined, so + // we should always try to reuse existing containers as much as possible! + // We need not only factory pattern, but also finder pattern here as well. + if (CIAO::debug_level () > 15) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) NodeApplication_Impl.cpp -" + "CIAO::NodeApplication_Impl::install -" + "creating all the containers. \n")); + } + + CORBA::ULong old_set_size = this->container_set_.size (); + + (void) this->create_all_containers (container_infos); + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) NodeApplication_Impl.cpp -" + "CIAO::NodeApplication_Impl::install -" + "create_all_containers() called.\n")); + } + + // For each container, invoke <install> operation, this will return + // the ComponentInfo for components installed in each container. + // Merge all the returned ComponentInfo, which will be used + // as the return value of this method. + CORBA::ULong const num_containers = container_infos.length (); + for (CORBA::ULong i = 0; i < num_containers; ++i) + { + Deployment::ComponentInfos_var comp_infos = + this->container_set_.at(i+old_set_size)-> + install (container_infos[i]); + + // Append the return sequence to the *big* return sequence + CORBA::ULong curr_len = retv->length (); + retv->length (curr_len + comp_infos->length ()); + + for (CORBA::ULong j = curr_len; j < retv->length (); j++) + retv[j] = comp_infos[j-curr_len]; + } + + // @@ Maybe we can optimize this. We can come up with a decision later. + // Cache a copy of the component object references for all the components + // installed on this NodeApplication. I know we can delegates these to the + // undelying containers, but in that case, we should loop + // all the containers to find the component object reference. - Gan + CORBA::ULong const comp_len = retv->length (); + for (CORBA::ULong len = 0; + len < comp_len; + ++len) + { + Component_State_Info tmp; + + tmp.state_ = NEW_BORN; + tmp.objref_ = + Components::CCMObject::_duplicate (retv[len].component_ref.in ()); + + //Since we know the type ahead of time...narrow is omitted here. + if (this->component_state_map_.rebind ( + retv[len].component_instance_name.in(), tmp)) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) NodeApplication_Impl.cpp -" + "CIAO::NodeApplication_Impl::install -" + "error binding component instance [%s] " + "into the map. \n", + retv[len].component_instance_name.in ())); + throw Deployment::InstallationFailure ( + "NodeApplication_Imp::install", + "Duplicate component instance name"); + } + } + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("CIAO_NodeApplication::install error\t\n"); + throw; + } + + return retv._retn (); +} + +void +CIAO::NodeApplication_Impl::remove_component (const char * inst_name) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Components::RemoveFailure)) +{ + ACE_DEBUG ((LM_DEBUG, "NA_I: removing component %s\n", + inst_name)); + + // Fetch the container object reference from the componet_container_map + ::Deployment::Container_var container_ref; + if (this->component_container_map_.find (inst_name, container_ref) != 0) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::remove_component, " + "invalid instance [%s] in the component_container_map.\n", + inst_name)); + throw ::Components::RemoveFailure (); + } + + // Remove this component instance from the node application + ACE_CString name (inst_name); + this->component_container_map_.unbind (name); + this->component_state_map_.unbind (name); + container_ref->remove_component (inst_name); +} + +void +CIAO::NodeApplication_Impl::passivate_component (const char * name) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Components::RemoveFailure)) +{ + Component_State_Info comp_state; + + if (this->component_state_map_.find (name, comp_state) != 0) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::passivate_component, " + "invalid instance [%s] \n", + name)); + throw Components::RemoveFailure (); + } + + if (CORBA::is_nil (comp_state.objref_.in ())) + { + ACE_DEBUG ((LM_DEBUG, "comp is nil\n")); + throw Components::RemoveFailure (); + } + + comp_state.objref_->ciao_passivate (); +} + +void +CIAO::NodeApplication_Impl::activate_component (const char * name) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::StartError)) +{ + Component_State_Info comp_state; + + if (this->component_state_map_.find (name, comp_state) != 0) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::activate_component, " + "invalid instance [%s] \n", + name)); + throw Deployment::StartError (); + } + + if (CORBA::is_nil (comp_state.objref_.in ())) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "comp is nil\n")); + throw Deployment::StartError (); + } + + comp_state.objref_->ciao_preactivate (); + + comp_state.objref_->ciao_activate (); + + comp_state.objref_->ciao_postactivate (); +} + + +void +CIAO::NodeApplication_Impl::remove () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // If we still have components installed, then do nothing + + if (this->component_state_map_.current_size () != 0) + return; + + // For each container, invoke <remove> operation to remove home and components. + CORBA::ULong const set_size = this->container_set_.size (); + for (CORBA::ULong i = 0; i < set_size; ++i) + { + if (CIAO::debug_level () > 5) + { + ACE_DEBUG ((LM_DEBUG, "NA: calling remove on container %i\n")); + } + + this->container_set_.at(i)->remove (); + } + + // Remove all containers + // Maybe we should also deactivate container object reference. + if (CIAO::debug_level () > 5) + { + ACE_DEBUG ((LM_DEBUG, "NA: remove all\n")); + } + + this->container_set_.remove_all (); + + if (CIAO::debug_level () > 1) + { + ACE_DEBUG ((LM_DEBUG, "Removed all containers from this NodeApplication!\n")); + } + + // For static deployment, ORB will be shutdown in the Static_NodeManager + if (this->static_entrypts_maps_ == 0) + { + this->orb_->shutdown (0); + ACE_DEBUG ((LM_DEBUG, "NA: shutdown\n")); + } +} + + +// Create a container interface, which will be hosted in this NodeApplication. +::Deployment::Container_ptr +CIAO::NodeApplication_Impl::create_container ( + const ::Deployment::Properties &properties) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Components::CreateFailure, + ::Components::InvalidConfiguration)) +{ + //if (CIAO::debug_level () > 1) + // ACE_DEBUG ((LM_DEBUG, "ENTERING: NodeApplication_Impl::create_container()\n")); + + CORBA::PolicyList_var policies + = this->configurator_.find_container_policies (properties); + + CIAO::Container_Impl *container_servant = 0; + + ACE_NEW_THROW_EX (container_servant, + CIAO::Container_Impl (this->orb_.in (), + this->poa_.in (), + this->get_objref (), + this->static_entrypts_maps_), + CORBA::NO_MEMORY ()); + + PortableServer::ServantBase_var safe_servant (container_servant); + + // @TODO: Need to decide a "component_installation" equivalent data + // structure to pass to the container, which will be used to + // suggest how to install the components. Each such data stucture + // should be correspond to one <process_collocation> tag in the XML + // file to describe the deployment plan. + container_servant->init (policies.ptr ()); + + PortableServer::ObjectId_var oid + = this->poa_->activate_object (container_servant); + + CORBA::Object_var obj + = this->poa_->id_to_reference (oid.in ()); + + ::Deployment::Container_var ci + = ::Deployment::Container::_narrow (obj.in ()); + + // Cached the objref in its servant. + container_servant->set_objref (ci.in ()); + + { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); + + this->container_set_.add (ci.in ()); + } + + //if (CIAO::debug_level () > 1) + // ACE_DEBUG ((LM_DEBUG, + // "LEAVING: NodeApplication_Impl::create_container()\n")); + return ci._retn (); +} + +// Remove a container interface. +void +CIAO::NodeApplication_Impl::remove_container (::Deployment::Container_ptr cref) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Components::RemoveFailure)) +{ + ACE_DEBUG ((LM_DEBUG, "ENTERING: NodeApplication_Impl::remove_container()\n")); + ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_); + + if (this->container_set_.object_in_set (cref) == 0) + { + throw Components::RemoveFailure(); + } + + cref->remove (); + + // @@ Deactivate object. + PortableServer::ObjectId_var oid + = this->poa_->reference_to_id (cref); + + this->poa_->deactivate_object (oid.in ()); + + // Should we remove the server still, even if the previous call failed. + if (this->container_set_.remove (cref) == -1) + { + throw ::Components::RemoveFailure (); + } + + ACE_DEBUG ((LM_DEBUG, "LEAVING: NodeApplication_Impl::remove_container()\n")); +} + +// Get containers +::Deployment::Containers * +CIAO::NodeApplication_Impl::get_containers () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return 0; +} + +CIAO::CIAO_Event_Service * +CIAO::NodeApplication_Impl:: +install_es (const ::CIAO::DAnCE::EventServiceDeploymentDescription & es_info) +ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::InstallationFailure)) +{ + try + { + ACE_DEBUG ((LM_DEBUG, "\nNodeApplication_Impl::install_es() called.\n\n")); + + CIAO_Event_Service_var ciao_es = + es_factory_.create (es_info.type, es_info.name.in ()); + + // Set up the event channel federations + if (es_info.type == CIAO::RTEC) + { + // Narrow the event service to CIAO_RT_Event_Service + ::CIAO::CIAO_RT_Event_Service_var ciao_rtes = + ::CIAO::CIAO_RT_Event_Service::_narrow (ciao_es.in ()); + + if (CORBA::is_nil (ciao_rtes.in ())) + throw ::Deployment::InstallationFailure (); + + // Set up the event channel federations + for (CORBA::ULong j = 0; j < es_info.addr_servs.length (); ++j) + { + bool retv = + ciao_rtes->create_addr_serv ( + es_info.addr_servs[j].name.in (), + es_info.addr_servs[j].port, + es_info.addr_servs[j].address); + + if (retv == false) + { + ACE_DEBUG ((LM_ERROR, "RTEC failed to create addr serv object\t\n")); + ACE_THROW_RETURN (::Deployment::InstallationFailure (), 0); + } + } + + for (CORBA::ULong j = 0; j < es_info.senders.length (); ++j) + { + bool retv = + ciao_rtes->create_sender ( + es_info.senders[j].addr_serv_id.in ()); + + if (retv == false) + { + ACE_DEBUG ((LM_ERROR, "RTEC failed to create UDP sender object\t\n")); + ACE_THROW_RETURN (::Deployment::InstallationFailure (), 0); + } + } + + for (CORBA::ULong j = 0; j < es_info.receivers.length (); ++j) + { + bool retv = + ciao_rtes->create_receiver ( + es_info.receivers[j].addr_serv_id.in (), + es_info.receivers[j].is_multicast, + es_info.receivers[j].listen_port); + + if (retv == false) + { + ACE_DEBUG ((LM_ERROR, "RTEC failed to create UDP receiver object\t\n")); + ACE_THROW_RETURN (::Deployment::InstallationFailure (), 0); + } + } + } + return ciao_es._retn (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("NodeApplication_Impl::finishLaunch\t\n"); + ACE_THROW_RETURN (::Deployment::InstallationFailure (), 0); + } + +} + + +ACE_CString * +CIAO::NodeApplication_Impl:: +create_connection_key (const Deployment::Connection & connection) +{ + ACE_CString * retv; + ACE_NEW_RETURN (retv, ACE_CString, 0); + + (*retv) += connection.instanceName.in (); + (*retv) += connection.portName.in (); + (*retv) += connection.endpointInstanceName.in (); + (*retv) += connection.endpointPortName.in (); + + if (CIAO::debug_level () > 3) + ACE_ERROR ((LM_ERROR, "The key is: %s\n", (*retv).c_str ())); + + return retv; +} + + +void +CIAO::NodeApplication_Impl:: +handle_facet_receptable_connection ( + Components::CCMObject_ptr comp, + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)) +{ + if (CIAO::debug_level () > 11) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::finishLaunch, " + "working on port name [%s] in instance [%s] \n", + connection.portName.in (), + connection.instanceName.in ())); + } + + if (add_connection) + { + ::Components::Cookie_var cookie = + comp->connect (connection.portName.in (), + connection.endpoint.in ()); + + ACE_CString key = (*create_connection_key (connection)); + if (CIAO::debug_level () > 10) + { + ACE_ERROR ((LM_ERROR, "[BINDING KEY]: %s\n", key.c_str ())); + } + this->cookie_map_.rebind (key, cookie); + + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::finishLaunch\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] connected.\n", + connection.instanceName.in (), + connection.portName.in (), + connection.endpointInstanceName.in (), + connection.endpointPortName.in ())); + } + } + else + { + ACE_CString key = (*create_connection_key (connection)); + ::Components::Cookie_var cookie; + if (CIAO::debug_level () > 6) + { + ACE_ERROR ((LM_ERROR, "[FINDING KEY]: %s\n", key.c_str ())); + } + if (this->cookie_map_.find (key, cookie) != 0) + { + ACE_ERROR ((LM_ERROR, "Error: Cookie Not Found!\n")); + throw Deployment::InvalidConnection (); + } + + comp->disconnect (connection.portName.in (), + cookie.in ()); + this->cookie_map_.unbind (key); + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::finishLaunch\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] disconnected.\n", + connection.instanceName.in (), + connection.portName.in (), + connection.endpointInstanceName.in (), + connection.endpointPortName.in ())); + } + } +} + + +void +CIAO::NodeApplication_Impl:: +handle_emitter_consumer_connection ( + Components::CCMObject_ptr comp, + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)) +{ + Components::EventConsumerBase_var consumer = + Components::EventConsumerBase::_narrow (connection.endpoint.in ()); + + if (CORBA::is_nil (consumer.in ())) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_emitter_consumer_connection, " + "for port name [%s] in instance [%s] ," + "there is an invalid endPoint. \n", + connection.portName.in (), + connection.instanceName.in ())); + throw Deployment::InvalidConnection (); + } + + if (CIAO::debug_level () > 11) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_emitter_consumer_connection, " + "working on port name [%s] in instance [%s] \n", + connection.portName.in (), + connection.instanceName.in ())); + } + + if (add_connection) + { + comp->connect_consumer (connection.portName.in (), + consumer.in ()); + + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_emitter_consumer_connection\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] connected.\n", + connection.instanceName.in (), + connection.portName.in (), + connection.endpointInstanceName.in (), + connection.endpointPortName.in ())); + } + } + else + { +// Operation not implemented by the CIDLC. +// comp->disconnect_consumer (connection.portName.in (), +// 0 +//); +// ACE_TRY_CHECK; + + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_emitter_consumer_connection\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] disconnected.\n", + connection.instanceName.in (), + connection.portName.in (), + connection.endpointInstanceName.in (), + connection.endpointPortName.in ())); + } + } +} + + +void +CIAO::NodeApplication_Impl:: +handle_publisher_consumer_connection ( + Components::CCMObject_ptr comp, + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)) +{ + Components::EventConsumerBase_var consumer = + Components::EventConsumerBase::_narrow (connection.endpoint.in ()); + + if (CORBA::is_nil (consumer.in ())) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_publisher_consumer_connection, " + "for port name [%s] in instance [%s] ," + "there is an invalid endPoint. \n", + connection.portName.in (), + connection.instanceName.in ())); + throw Deployment::InvalidConnection (); + } + + if (CIAO::debug_level () > 11) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_publisher_consumer_connection, " + "working on port name [%s] in instance [%s] \n", + connection.portName.in (), + connection.instanceName.in ())); + } + + if (add_connection) + { + ::Components::Cookie_var cookie = + comp->subscribe (connection.portName.in (), + consumer.in ()); + + ACE_CString key = (*create_connection_key (connection)); + this->cookie_map_.rebind (key, cookie); + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_publisher_consumer_connection\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] connected.\n", + connection.instanceName.in (), + connection.portName.in (), + connection.endpointInstanceName.in (), + connection.endpointPortName.in ())); + } + } + else // remove the connection + { + ACE_CString key = (*create_connection_key (connection)); + ::Components::Cookie_var cookie; + + if (CIAO::debug_level () > 6) + { + ACE_ERROR ((LM_ERROR, "[FINDING KEY]: %s\n", key.c_str ())); + } + if (this->cookie_map_.find (key, cookie) != 0) + { + ACE_ERROR ((LM_ERROR, "Error: Cookie Not Found!\n")); + throw Deployment::InvalidConnection (); + } + + comp->unsubscribe (connection.portName.in (), + cookie.in ()); + this->cookie_map_.unbind (key); + + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_publisher_consumer_connection\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] disconnected.\n", + connection.instanceName.in (), + connection.portName.in (), + connection.endpointInstanceName.in (), + connection.endpointPortName.in ())); + } + } +} + + +void +CIAO::NodeApplication_Impl:: +handle_publisher_es_connection ( + Components::CCMObject_ptr comp, + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)) +{ + if (! this->_is_publisher_es_conn (connection)) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_publisher_es_connection: " + "Unsupported event connection type\n")); + throw CORBA::NO_IMPLEMENT (); + } + + const CIAO::CIAO_Event_Service_ptr event_service = + connection.event_service; + + if (CORBA::is_nil (event_service)) + { + ACE_DEBUG ((LM_DEBUG, "Nil event_service\n")); + throw Deployment::InvalidConnection (); + } + + // supplier ID + ACE_CString sid (connection.instanceName.in ()); + sid += "_"; + sid += connection.portName.in (); + + if (add_connection) + { + ::Components::Cookie_var cookie = + comp->subscribe (connection.portName.in (), + event_service); + + ACE_CString key = (*create_connection_key (connection)); + this->cookie_map_.rebind (key, cookie); + + // Create a supplier_config and register it to ES + CIAO::Supplier_Config_var supplier_config = + event_service->create_supplier_config (); + + supplier_config->supplier_id (sid.c_str ()); + event_service->connect_event_supplier (supplier_config.in ()); + supplier_config->destroy (); + + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_publisher_es_connection\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] connected.\n", + connection.instanceName.in (), + connection.portName.in (), + connection.endpointInstanceName.in (), + connection.endpointPortName.in ())); + } + } + else // remove the connection + { + ACE_CString key = (*create_connection_key (connection)); + ::Components::Cookie_var cookie; + + if (CIAO::debug_level () > 6) + { + ACE_ERROR ((LM_ERROR, "[FINDING KEY]: %s\n", key.c_str ())); + } + if (this->cookie_map_.find (key, cookie) != 0) + { + ACE_ERROR ((LM_ERROR, "Error: Cookie Not Found!\n")); + throw Deployment::InvalidConnection (); + } + + comp->unsubscribe (connection.portName.in (), + cookie.in ()); + this->cookie_map_.unbind (key); + event_service->disconnect_event_supplier (sid.c_str ()); + + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_publisher_es_connection\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] disconnected.\n", + connection.instanceName.in (), + connection.portName.in (), + connection.endpointInstanceName.in (), + connection.endpointPortName.in ())); + } + } +} + + +void +CIAO::NodeApplication_Impl:: +handle_es_consumer_connection ( + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)) +{ + if (! this->_is_es_consumer_conn (connection)) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_es_consumer_connection: " + "Unsupported event connection type\n")); + throw CORBA::NO_IMPLEMENT (); + } + + // Get ES object + const CIAO::CIAO_Event_Service_ptr event_service = + connection.event_service; + + if (CORBA::is_nil (event_service)) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_es_consumer_connection: " + "NIL event_service\n")); + throw Deployment::InvalidConnection (); + } + + // Get consumer object + Components::EventConsumerBase_var consumer = + Components::EventConsumerBase::_narrow (connection.endpoint.in ()); + + if (CORBA::is_nil (consumer.in ())) + { + ACE_ERROR ((LM_ERROR, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_es_consumer_connection: " + "Nil consumer port object reference\n")); + throw Deployment::InvalidConnection (); + } + + // consumer ID + ACE_CString cid (connection.instanceName.in ()); + cid += "_"; + cid += connection.portName.in (); + cid += "_consumer"; + + if (add_connection) + { + CIAO::Consumer_Config_var consumer_config = + event_service->create_consumer_config (); + + consumer_config->consumer_id (cid.c_str ()); + consumer_config->consumer (consumer.in ()); + + // Need to setup a filter, if it's specified in the descriptor + for (CORBA::ULong i = 0; i < connection.config.length (); ++i) + { + if (ACE_OS::strcmp (connection.config[i].name.in (), + "EventFilter") != 0) + continue; + + // Extract the filter information + CIAO::DAnCE::EventFilter *filter = 0; + connection.config[i].value >>= filter; + + CORBA::ULong size = (*filter).sources.length (); + + if ((*filter).type == DAnCE::CONJUNCTION) + consumer_config->start_conjunction_group (size); + else if ((*filter).type == DAnCE::DISJUNCTION) + consumer_config->start_disjunction_group (size); + + for (CORBA::ULong j = 0; j < size; ++j) + { + consumer_config->insert_source ((*filter).sources[j]); + } + } + + event_service->connect_event_consumer (consumer_config.in ()); + consumer_config->destroy (); + + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_es_consumer_connection\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] connected.\n", + connection.endpointInstanceName.in (), + connection.endpointPortName.in (), + connection.instanceName.in (), + connection.portName.in ())); + } + } + else // remove the connection + { + event_service->disconnect_event_consumer (cid.c_str ()); + + if (CIAO::debug_level () > 6) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) - NodeApplication_Impl.cpp, " + "CIAO::NodeApplication_Impl::handle_es_consumer_connection\n" + "[INSTANCE:PORT] : [%s:%s] --> [%s:%s] disconnected.\n", + connection.endpointInstanceName.in (), + connection.endpointPortName.in (), + connection.instanceName.in (), + connection.portName.in ())); + } + } +} + +// Below code is not used at this time. +void +CIAO::NodeApplication_Impl::build_event_connection ( + const Deployment::Connection & connection, + bool add_or_remove) + ACE_THROW_SPEC ((Deployment::InvalidConnection, + CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, "CIAO::NodeApplication_Impl::build_connection ()!!!\n")); + + ACE_DEBUG ((LM_DEBUG, "instanceName: %s\n", connection.instanceName.in ())); + ACE_DEBUG ((LM_DEBUG, "portName: %s\n", connection.portName.in ())); + + ACE_DEBUG ((LM_DEBUG, "consumer Component Name: %s\n", connection.endpointInstanceName.in ())); + ACE_DEBUG ((LM_DEBUG, "consumer Port Name: %s\n", connection.endpointPortName.in ())); + + ACE_DEBUG ((LM_DEBUG, "portkind: ")); + switch (connection.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; + default: + ACE_DEBUG ((LM_DEBUG, "Unknow\n")); break; + } + + const CIAO::CIAO_Event_Service_ptr event_service = + connection.event_service; + + + // Get the consumer port object reference and put it into "consumer" + Components::EventConsumerBase_var consumer = + Components::EventConsumerBase::_narrow (connection.endpoint.in ()); + + if (CORBA::is_nil (consumer.in ())) + { + ACE_DEBUG ((LM_DEBUG, "Nil consumer port object reference\n")); + throw Deployment::InvalidConnection (); + } + + // Get the supplier component object reference. + ACE_CString supplier_comp_name = connection.instanceName.in (); + + ACE_DEBUG ((LM_DEBUG, "source component name is: %s\n", supplier_comp_name.c_str ())); + Component_State_Info comp_state; + if (this->component_state_map_.find (supplier_comp_name, comp_state) != 0) + { + ACE_DEBUG ((LM_DEBUG, "Nil source component object reference\n")); + throw Deployment::InvalidConnection (); + } + + // Get the consumer component object reference. + ACE_CString consumer_comp_name = connection.endpointInstanceName.in (); + + ACE_DEBUG ((LM_DEBUG, "consumer component name is: %s\n", consumer_comp_name.c_str ())); + + if (CORBA::is_nil (event_service)) + { + ACE_DEBUG ((LM_DEBUG, "Nil event_service\n")); + throw Deployment::InvalidConnection (); + } + + // supplier ID + ACE_CString sid (connection.instanceName.in ()); + sid += "_"; + sid += connection.portName.in (); + + // consumer ID + ACE_CString cid (connection.endpointInstanceName.in ()); + cid += "_"; + cid += connection.endpointPortName.in (); + cid += "_consumer"; + + //ACE_DEBUG ((LM_DEBUG, "Publisher: %s\n", sid.c_str ())); + ACE_DEBUG ((LM_DEBUG, "Subscriber: %s\n", cid.c_str ())); + + + if (add_or_remove == true) + { + CIAO::Supplier_Config_var supplier_config = + event_service->create_supplier_config (); + + supplier_config->supplier_id (sid.c_str ()); + event_service->connect_event_supplier (supplier_config.in ()); + supplier_config->destroy (); + + CIAO::Consumer_Config_var consumer_config = + event_service->create_consumer_config (); + + consumer_config->consumer_id (cid.c_str ()); + consumer_config->consumer (consumer.in ()); + + event_service->connect_event_consumer (consumer_config.in ()); + + consumer_config->destroy (); + } + else + { + event_service->disconnect_event_supplier (sid.c_str ()); + event_service->disconnect_event_consumer (cid.c_str ()); + } + + ACE_DEBUG ((LM_DEBUG, "CIAO::NodeApplication_Impl::build_connection () completed!!!!\n")); +} + +bool +CIAO::NodeApplication_Impl:: +_is_es_consumer_conn (Deployment::Connection conn) +{ + if (conn.kind == Deployment::EventConsumer && + ACE_OS::strcmp (conn.endpointPortName, "CIAO_ES") == 0) + return true; + else + return false; +} + +bool +CIAO::NodeApplication_Impl:: +_is_publisher_es_conn (Deployment::Connection conn) +{ + if (conn.kind == Deployment::EventPublisher && + ACE_OS::strcmp (conn.endpointPortName, "CIAO_ES") == 0) + return true; + else + return false; +} diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.h b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.h new file mode 100644 index 00000000000..c412b1aa9f5 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.h @@ -0,0 +1,371 @@ +//$Id$ + +/**======================================================== + * + * @file NodeApplication_Impl.h + * + * @Brief This file contains the implementation of + * the NodeApplication interface. + * + * @author Tao Lu <lu@dre.vanderbilt.edu> + * @author Gan Deng <dengg@dre.vanderbilt.edu> + *========================================================*/ + +#ifndef NODEAPPLICATION_IMPL_H +#define NODEAPPLICATION_IMPL_H +#include /**/ "ace/pre.h" + +#include "CIAO_NodeApplication_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Synch.h" +#include "ace/Synch_Traits.h" +#include "ace/SString.h" +#include "ace/Hash_Map_Manager_T.h" +#include "tao/ORB.h" +#include "ciao/Deployment_NodeApplicationS.h" +#include "ciao/Server_init.h" +#include "ciao/CIAO_common.h" +#include "ciao/Object_Set_T.h" +#include "ciaosvcs/Events/CIAO_EventService_Factory_impl.h" +#include "ciaosvcs/Events/CIAO_Events_Base/CIAO_EventsS.h" + +#include "NodeApp_Configurator.h" +#include "Container_Base.h" + +using CIAO::Utility::write_IOR; + +/** + * + * @class NodeApplication_Impl + * + * @brief This class implements the NodeApplication interface. + * This interface is semantically very simillar to container + * in the old DnC spec. However this class will also be used + * as a Server for hosting home/component. This way we reduce the + * complexity of the framework by omitting the componentserver layer. + * + * @@TODO add configuration capabilities. Threading is one of them. + * + * @@Assumptions: + * 1. Now the implementation is not thread safe. + * // @@Gan, the above assumption is _really_ bad. Could you please + * use the lock in the imeplementation to do some simple + * prootections. + **/ + +namespace CIAO +{ + // @@ Gan, as we discussed before can you please wrap this + // implementation in a namespace Node_Application or whatever to + // signify that it belongs to another software piece of CIAO? + class NODEAPPLICATION_Export NodeApplication_Impl + : public virtual POA_Deployment::NodeApplication + { + public: + enum Component_State + { + NEW_BORN, PRE_ACTIVE, ACTIVE, POST_ACTIVE, PASSIVE, DEACTIVATED + }; + + typedef struct _component_state_info + { + Components::CCMObject_var objref_; + Component_State state_; + } Component_State_Info; + + NodeApplication_Impl (CORBA::ORB_ptr o, + PortableServer::POA_ptr p, + NodeApp_Configurator &c, + const Static_Config_EntryPoints_Maps* static_entrypts_maps =0); + + /// Default destructor. + virtual ~NodeApplication_Impl (void); + + /** + * @brief This operation dose 2 things. + * 1. Get the external connction (facet and Event source) + * and connect them to the local receptacle/event sink. + * 2. If the start augment is true, start the Components. + * @Note: + * The connection containes the object ref of the provided object + * reference (facet/event consumer) of components from other NodeApplications. + * However the name field stores the name of the port on the local component. + */ + virtual void + finishLaunch (const Deployment::Connections & connections, + CORBA::Boolean start, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError, + Deployment::InvalidConnection)); + + virtual void + start () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + /*------------- CIAO specific IDL operations (idl)---------- + * + *-----------------------------------------------------------*/ + + virtual void + ciao_preactivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + virtual void + ciao_postactivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError)); + + virtual void + ciao_passivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)); + + /// Initialize the NodeApplication + virtual CORBA::Long init () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Start install homes and components. + virtual ::Deployment::ComponentInfos * + install (const ::Deployment::NodeImplementationInfo & node_impl_info) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::UnknownImplId, + ::Deployment::ImplEntryPointNotFound, + ::Deployment::InstallationFailure, + ::Components::InvalidConfiguration)); + + /// Install a number of CIAO_Event_Service objects within the NA + virtual ::CIAO::CIAO_Event_Service * + install_es (const ::CIAO::DAnCE::EventServiceDeploymentDescription & es_info) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::InstallationFailure)); + + /// Get the object reference of the NodeApplicationManager. + /// This might come in handy later. + virtual ::CORBA::Object_ptr + get_node_application_manager () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Access the readonly attribute. + virtual ::Deployment::Properties * + properties () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Remove a component instance from the NodeApplication + virtual void remove_component (const char * inst_name) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Components::RemoveFailure)); + + virtual void activate_component (const char * name) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::StartError)); + + virtual void passivate_component (const char * name) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Components::RemoveFailure)); + + /// Remove everything inside including all components and homes. + virtual void remove () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Create a container interface, which will be hosted in this NodeApplication. + virtual ::Deployment::Container_ptr + create_container (const ::Deployment::Properties &properties) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Components::CreateFailure, + ::Components::InvalidConfiguration)); + + /// Remove a container interface. + virtual void remove_container (::Deployment::Container_ptr cref) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Components::RemoveFailure)); + + /// Get all container object refs + virtual ::Deployment::Containers * get_containers () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /*------------- CIAO specific helper functions (C++)--------- + * + *-----------------------------------------------------------*/ + + /// Get the containing POA. This operation does *not* + /// increase the reference count of the POA. + virtual PortableServer::POA_ptr _default_POA (void); + + /// Return the cached object reference of this NodeApplication object. + /// This operation does *NOT* increase the reference count. + ::Deployment::NodeApplication_ptr + get_objref (); + + /*------- CIAO helper functions for pub/sub service ------- + * + *--------------------------------------------------------*/ + + /// Set up a connection using the CIAO_Event_Service, which + /// is available as a field in the <Deployment::Connection> + /// struct type. + /// If <add_or_remove> input parameter is true, then we will + /// add the event connection, otherwise we will remove the + /// event connection. + void build_event_connection ( + const Deployment::Connection & connection, + bool add_or_remove) + ACE_THROW_SPEC ((Deployment::InvalidConnection, + CORBA::SystemException)); + + protected: + /// If <add_connection> is "false", then we shall "remove" + /// the connections, otherwise we will add these connections. + virtual void + finishLaunch_i (const Deployment::Connections & connections, + CORBA::Boolean start, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError, + Deployment::InvalidConnection)); + virtual void + handle_facet_receptable_connection ( + Components::CCMObject_ptr comp, + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)); + + virtual void + handle_emitter_consumer_connection ( + Components::CCMObject_ptr comp, + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)); + + virtual void + handle_publisher_consumer_connection ( + Components::CCMObject_ptr comp, + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)); + + virtual bool + _is_es_consumer_conn (Deployment::Connection conn); + + virtual bool + _is_publisher_es_conn (Deployment::Connection conn); + + /// Register the publisher to the CIAO event service + /// The only fields of <connection> struct used in this method + /// are: <type>, <event_service>, <instanceName>, <portName>. + virtual void + handle_publisher_es_connection ( + Components::CCMObject_ptr comp, + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)); + + /// Register the consumer to the CIAO event service + virtual void + handle_es_consumer_connection ( + const Deployment::Connection & connection, + CORBA::Boolean add_connection) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidConnection)); + + /// Create and initialize all the containers + virtual CORBA::Long create_all_containers ( + const ::Deployment::ContainerImplementationInfos & container_infos) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Create a "key" for the connection + virtual ACE_CString * + create_connection_key (const Deployment::Connection & connection); + + /// To build a map between a component instance and its container + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + Deployment::Container_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> Component_Container_Map; + typedef Component_Container_Map::iterator Component_Container_Iterator; + Component_Container_Map component_container_map_; + + + /// To store all created Component objects as well as their lifecycle + /// states.. + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + Component_State_Info, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> CCMComponent_Map; + typedef CCMComponent_Map::iterator Component_Iterator; + CCMComponent_Map component_state_map_; + + /// A Map which stores all the connection cookies + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + ::Components::Cookie_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> Cookie_Map; + typedef Cookie_Map::iterator Cookie_Map_Iterator; + Cookie_Map cookie_map_; + + /// Synchronize access to the object set. + TAO_SYNCH_MUTEX lock_; + + /// Keep a list of managed Container objects. + Object_Set<Deployment::Container, Deployment::Container_var> container_set_; + + /// Keep a pointer to the managing ORB serving this servant. + CORBA::ORB_var orb_; + + /// Keep a pointer to the managing POA. + // @@Gan/Jai, which POA is this? Same as the component POA or a + // different one. My sense is that its different. Could you please + //document it? + PortableServer::POA_var poa_; + + // Configurator for allocating NodeApp resources and policies + NodeApp_Configurator &configurator_; + + /// Cached properties + Deployment::Properties properties_; + + /// And a reference to the NodeApplicationManager that created us. + ::CORBA::Object_var node_app_manager_; + + /// Cache the object reference (of ourselves). + ::Deployment::NodeApplication_var objref_; + + /// A factory to create CIAO event services + EventService_Factory_impl es_factory_; + + /// Cache the (NA specific) installation info of all the + /// CIAO_Event_Services + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + DAnCE::EventServiceDeploymentDescriptions_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> ES_Installation_Map; + typedef ES_Installation_Map::iterator ES_Installation_Map_Iterator; + ES_Installation_Map es_info_map_; + + const Static_Config_EntryPoints_Maps* static_entrypts_maps_; + private: + /// Default constructor, noop + NodeApplication_Impl(void); + }; +} + +#if defined (__ACE_INLINE__) +# include "NodeApplication_Impl.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* NODEAPPLICATION_IMPL_H */ diff --git a/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.inl b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.inl new file mode 100644 index 00000000000..2fefdcc84d4 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.inl @@ -0,0 +1,78 @@ +/* -*- C++ -*- */ +// $Id$ +#include "Configurator_Factory.h" + +ACE_INLINE +CIAO::NodeApplication_Impl:: +NodeApplication_Impl (CORBA::ORB_ptr o, + PortableServer::POA_ptr p, + NodeApp_Configurator &c, + const Static_Config_EntryPoints_Maps* static_entrypts_maps) + : orb_ (CORBA::ORB::_duplicate (o)), + poa_ (PortableServer::POA::_duplicate (p)), + configurator_ (c), + es_factory_ (o, p), + static_entrypts_maps_ (static_entrypts_maps) +{ +} + +// Access the readonly attribute +ACE_INLINE +Deployment::Properties * +CIAO::NodeApplication_Impl::properties () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + Deployment::Properties * tmp = 0; + + ACE_NEW_THROW_EX (tmp, + Deployment::Properties (this->properties_), + CORBA::NO_MEMORY ()); + + return tmp; +} + +ACE_INLINE +PortableServer::POA_ptr +CIAO::NodeApplication_Impl::_default_POA (void) +{ + return PortableServer::POA::_duplicate (this->poa_.in ()); +} + + +ACE_INLINE +CORBA::Object_ptr +CIAO::NodeApplication_Impl::get_node_application_manager () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return ::CORBA::Object::_duplicate (this->node_app_manager_.in ()); +} + +/* +ACE_INLINE void +CIAO::NodeApplication_Impl:: +set_objref (Components::Deployment::ServerActivator_ptr act, + const Components::ConfigValues &config, + Components::Deployment::ComponentServer_ptr cs) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (!CORBA::is_nil (this->node_app_manager_.in ()) || + !CORBA::is_nil (this->objref_.in ())) + throw CORBA::BAD_INV_ORDER (); + + this->config_ = new Components::ConfigValues (config); + this->activator_ = Components::Deployment::ServerActivator::_duplicate (act); + this->objref_ = Components::Deployment::ComponentServer::_duplicate (cs); +} +*/ + +ACE_INLINE ::Deployment::NodeApplication_ptr +CIAO::NodeApplication_Impl:: +get_objref () +{ + if (CORBA::is_nil (this->objref_.in ())) + { + this->objref_ = this->_this (); + } + + return this->objref_.in (); +} diff --git a/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.cpp b/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.cpp new file mode 100644 index 00000000000..b0dfb8a9ac0 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.cpp @@ -0,0 +1,448 @@ +// $Id$ + +#include "RTConfig_Manager.h" +#include "ciao/CIAO_common.h" +#include "ace/SString.h" + +#if !defined (__ACE_INLINE__) +# include "RTConfig_Manager.inl" +#endif /* __ACE_INLINE__ */ + +void +CIAO::RTResource_Config_Manager::init (RTCORBA::RTORB_ptr rtorb) +{ + this->rtorb_ = RTCORBA::RTORB::_duplicate (rtorb); +} + +void +CIAO::RTResource_Config_Manager::print_resources +(const CIAO::DAnCE::ServerResource &server_resource) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + const CIAO::DAnCE::ORBResource &orb_resource + = server_resource.orb_config.orb_resources[0]; + + CORBA::ULong i; + + // Creating and binding name with RT Threadpool + for (i = 0; i < orb_resource.threadpool_list.length (); ++i) + { + ACE_DEBUG ((LM_DEBUG, + "-RTResource_Config_Manager::print_resource threadpool: %s\n" + "\tStack size: %d\n" + "\tStatic: %d\n" + "\tDynamic %d\n" + "\tDefault Prio: %d\n" + "\tBuffering %s\n" + "\tMax Buffered: %d\n" + "\tBuffer Size %d\n", + orb_resource.threadpool_list[i].Id.in (), + orb_resource.threadpool_list[i].stacksize, + orb_resource.threadpool_list[i].static_threads, + orb_resource.threadpool_list[i].dynamic_threads, + orb_resource.threadpool_list[i].default_priority, + (orb_resource.threadpool_list[i].allow_request_buffering ? "Y" : "N"), + orb_resource.threadpool_list[i].max_buffered_requests, + orb_resource.threadpool_list[i].max_request_buffer_size)); + } + + for (i = 0; i < orb_resource.threadpool_with_lanes_list.length (); ++i) + { + ACE_DEBUG ((LM_DEBUG, + "-RTResource_Config_Manager::print_resource threadpool_with %d, lanes: %s\n", + orb_resource.threadpool_with_lanes_list[i].threadpool_lanes.length (), + orb_resource.threadpool_with_lanes_list[i].Id.in ())); + + for (CORBA::ULong l = 0; + l < orb_resource.threadpool_with_lanes_list[i].threadpool_lanes.length (); + ++l) + { + ACE_DEBUG ((LM_DEBUG, + "\tLane %d:\n" + "\t\tPriority: %d\n" + "\t\tStatic: %d\n" + "\t\tDynamic: %d\n", + l, + orb_resource.threadpool_with_lanes_list[i].threadpool_lanes[l].lane_priority, + orb_resource.threadpool_with_lanes_list[i].threadpool_lanes[l].static_threads, + orb_resource.threadpool_with_lanes_list[i].threadpool_lanes[l].dynamic_threads)); + } + ACE_DEBUG ((LM_DEBUG, + "\tStack size: %d\n" + "\tBorrowing: %s\n" + "\tBuffering %s\n" + "\tMax Buffered: %d\n" + "\tBuffer Size %d\n", + orb_resource.threadpool_with_lanes_list[i].stacksize, + (orb_resource.threadpool_with_lanes_list[i].allow_borrowing ? "Y" : "N"), + (orb_resource.threadpool_with_lanes_list[i].allow_request_buffering ? "Y" : "N"), + orb_resource.threadpool_with_lanes_list[i].max_buffered_requests, + orb_resource.threadpool_with_lanes_list[i].max_request_buffer_size)); + } + + for (i = 0; i < orb_resource.connection_bands_list.length (); ++i) + { + ACE_DEBUG ((LM_DEBUG, + "-RTResource_Config_Manager::print_resource connection %d bands: %s\n", + orb_resource.connection_bands_list[i].bands.length (), + orb_resource.connection_bands_list[i].Id.in ())); + + for (CORBA::ULong l = 0; + l < orb_resource.connection_bands_list[i].bands.length (); + ++l) + { + ACE_DEBUG ((LM_DEBUG, + "\tBand %d Prio: %d -- %d\n", + l, + orb_resource.connection_bands_list[i].bands[l].low, + orb_resource.connection_bands_list[i].bands[l].high)); + } + } +} + +void +CIAO::RTResource_Config_Manager::init_resources +(const CIAO::DAnCE::ServerResource &server_resource) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, + "RTResource_Config_Manager::init_resource.\n")); + + if (CORBA::is_nil (this->rtorb_.in())) + { + ACE_ERROR ((LM_ERROR, + "RTResource_Config_Manager has not been properly initialized.\n")); + throw CORBA::INTERNAL (); + } + + this->print_resources (server_resource); + // return; + + const CIAO::DAnCE::ORBResource &orb_resource + = server_resource.orb_config.orb_resources[0]; + + CORBA::ULong i; + + // Creating and binding name with RT Threadpool + for (i = 0; i < orb_resource.threadpool_list.length (); ++i) + { + ACE_DEBUG ((LM_DEBUG, + "RTResource_Config_Manager::init_resource threadpool: %s\n", + orb_resource.threadpool_list[i].Id.in ())); + RTCORBA::ThreadpoolId thr_id = + this->rtorb_->create_threadpool + (orb_resource.threadpool_list[i].stacksize, + orb_resource.threadpool_list[i].static_threads, + orb_resource.threadpool_list[i].dynamic_threads, + orb_resource.threadpool_list[i].default_priority, + orb_resource.threadpool_list[i].allow_request_buffering, + orb_resource.threadpool_list[i].max_buffered_requests, + orb_resource.threadpool_list[i].max_request_buffer_size); + // Simply pass back the exception here + // for now. We need to have a better way + // to handle execption here. + if (this->threadpool_map_.bind (orb_resource.threadpool_list[i].Id.in (), + thr_id) != 0) + { + ACE_ERROR ((LM_ERROR, "Error binding thread pool Id: %s to map when initializing RTNodeApplication resources.\n", orb_resource.threadpool_list[i].Id.in ())); + throw CORBA::INTERNAL (); + } + else + { + ACE_DEBUG ((LM_DEBUG, + "RTResource_Config_Manager::init_resource added thread pool: %s\n", + orb_resource.threadpool_list[i].Id.in ())); + } + } + + for (i = 0; i < orb_resource.threadpool_with_lanes_list.length (); ++i) + { + ACE_DEBUG ((LM_DEBUG, + "RTResource_Config_Manager::init_resource threadpool_with %d, lanes: %s\n", + orb_resource.threadpool_with_lanes_list[i].threadpool_lanes.length (), + orb_resource.threadpool_with_lanes_list[i].Id.in ())); + + // Duplicate RTCORBA lanes + RTCORBA::ThreadpoolLanes lanes + (orb_resource.threadpool_with_lanes_list[i].threadpool_lanes.length ()); + lanes.length (orb_resource.threadpool_with_lanes_list[i].threadpool_lanes.length ()); + + for (CORBA::ULong l = 0; + l < orb_resource.threadpool_with_lanes_list[i].threadpool_lanes.length (); + ++l) + { + lanes[l].lane_priority + = orb_resource.threadpool_with_lanes_list[i].threadpool_lanes[l].lane_priority; + lanes[l].static_threads + = orb_resource.threadpool_with_lanes_list[i].threadpool_lanes[l].static_threads; + lanes[l].dynamic_threads + = orb_resource.threadpool_with_lanes_list[i].threadpool_lanes[l].dynamic_threads; + } + + RTCORBA::ThreadpoolId thr_id = + this->rtorb_->create_threadpool_with_lanes + (orb_resource.threadpool_with_lanes_list[i].stacksize, + lanes, + orb_resource.threadpool_with_lanes_list[i].allow_borrowing, + orb_resource.threadpool_with_lanes_list[i].allow_request_buffering, + orb_resource.threadpool_with_lanes_list[i].max_buffered_requests, + orb_resource.threadpool_with_lanes_list[i].max_request_buffer_size); + // Simply pass back the exception here + // for now. We need to have a better way + // to handle execption here. + + if (this->threadpool_map_.bind (orb_resource.threadpool_with_lanes_list[i].Id.in (), + thr_id) != 0) + { + ACE_ERROR ((LM_ERROR, + "Error binding thread pool name: %s to map when " + "initializing RTNodeApplication resources.\n", + orb_resource.threadpool_with_lanes_list[i].Id.in ())); + throw CORBA::INTERNAL (); + } + + else + { + ACE_DEBUG ((LM_DEBUG, + "RTResource_Config_Manager::init_resource added thread pool with lanes: %s\n", + orb_resource.threadpool_with_lanes_list[i].Id.in ())); + } + } + + for (i = 0; i < orb_resource.connection_bands_list.length (); ++i) + { + RTCORBA::PriorityBands + safebands(orb_resource.connection_bands_list[i].bands.length ()); + safebands.length (orb_resource.connection_bands_list[i].bands.length ()); + + for (CORBA::ULong l = 0; + l < orb_resource.connection_bands_list[i].bands.length (); + ++l) + { + safebands[l].low = orb_resource.connection_bands_list[i].bands[l].low; + safebands[l].high = orb_resource.connection_bands_list[i].bands[l].high; + } + + if (this->priority_bands_map_.bind (orb_resource.connection_bands_list[i].Id.in (), + safebands) != 0) + { + ACE_ERROR ((LM_ERROR, + "Error binding priority bands name: %s to map " + "when initializing RTNodeApplication resources.\n", + orb_resource.connection_bands_list[i].Id.in ())); + throw CORBA::INTERNAL (); + } + else + { + ACE_DEBUG ((LM_DEBUG, + "RTResource_Config_Manager::init_resource added connection bands: %s\n", + orb_resource.connection_bands_list[i].Id.in ())); + } + } + + // now initialize the policy set part of it. + // server_resource.orb_config.policy_set + const CIAO::DAnCE::PolicySets &sets = server_resource.orb_config.policy_set; + for (CORBA::ULong i = 0; i < sets.length (); ++i) + { + CORBA::ULong const np = sets[i].policies.length (); + if (np == 0) + continue; + + CORBA::PolicyList_var policy_list = new CORBA::PolicyList (np); + policy_list->length (np); + + // Create a list of policies + for (CORBA::ULong pc = 0; pc < np; ++pc) + { + policy_list[pc] = this->create_single_policy (sets[i].policies[pc]); + } + + // Bind the policy list to the name. The bind operation should + // surrender the ownership of the newly created PolicyList + // sequence to the map. + if (this->policy_map_.bind (sets[i].Id.in (), + policy_list) != 0) + { + ACE_ERROR ((LM_ERROR, + "Error binding Policy_Set with name: %s\n", + sets[i].Id.in ())); + throw CORBA::INTERNAL (); + } + else + { + ACE_DEBUG ((LM_DEBUG, + "RTResource_Config_Manager::init_resource added policy set: %s\n", + sets[i].Id.in ())); + } + } +} + +void +CIAO::RTResource_Config_Manager::fini () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + TP_MAP::ITERATOR iter = this->threadpool_map_.begin (); + TP_MAP::ITERATOR end = this->threadpool_map_.end (); + + for (; iter != end; ++iter) + { + this->rtorb_->destroy_threadpool ((*iter).int_id_); + } + +} + +RTCORBA::ThreadpoolId +CIAO::RTResource_Config_Manager::find_threadpool_by_name (const char *name) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (name == 0) + { + ACE_ERROR ((LM_ERROR, + "Invalid name string found in \"find_threadpool_by_name\"\n")); + ACE_THROW_RETURN (CORBA::BAD_PARAM (), 0); + } + + + RTCORBA::ThreadpoolId ret_id = 0; // return id + + if (this->threadpool_map_.find (name, ret_id) != 0) + { + ACE_ERROR ((LM_ERROR, + "Unable to find a threadpool named %s\n", + name)); + ACE_THROW_RETURN (CORBA::INTERNAL (), 0); + } + + return ret_id; +} + +RTCORBA::PriorityBands * +CIAO::RTResource_Config_Manager::find_priority_bands_by_name (const char *name) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (name == 0) + { + ACE_ERROR ((LM_ERROR, + "Invalid name string found in \"find_priority_bands_by_name\"\n")); + ACE_THROW_RETURN (CORBA::BAD_PARAM (), 0); + } + + PB_MAP::ENTRY *entry = 0; + + if (this->priority_bands_map_.find (name, entry) != 0) + { + ACE_ERROR ((LM_ERROR, + "Unable to find a connection bands named %s\n", + name)); + ACE_THROW_RETURN (CORBA::INTERNAL (), 0); + } + + RTCORBA::PriorityBands_var retv = new RTCORBA::PriorityBands; + (*retv.ptr ()) = (*entry->int_id_.ptr ()); + return retv._retn (); +} + +CORBA::PolicyList * +CIAO::RTResource_Config_Manager::find_policies_by_name (const char *name) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (name == 0) + { + ACE_ERROR ((LM_ERROR, + "Invalid name string found in \"find_policies_by_name\"\n")); + ACE_THROW_RETURN (CORBA::BAD_PARAM (), 0); + } + + + ACE_DEBUG ((LM_DEBUG, "RTResource_Config_Manager::find_policies_by_name: %s\n", + name)); + + POLICY_MAP::ENTRY *entry = 0; + + if (this->policy_map_.find (name, entry) != 0) + { + ACE_ERROR ((LM_ERROR, + "Unable to find a PolicyList named %s\n", + name)); + ACE_THROW_RETURN (CORBA::INTERNAL (), 0); + } + + // duplicate the sequence PolicyList. + CORBA::PolicyList_var retv = + new CORBA::PolicyList (entry->int_id_.in ()); + + ACE_DEBUG ((LM_DEBUG, "RTResource_Config_Manager::find_policies_by_name ok.\n")); + + return retv._retn (); +} + +CORBA::Policy_ptr +CIAO::RTResource_Config_Manager::create_single_policy +(const CIAO::DAnCE::PolicyDef &policy_def) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG, + "RTResource_Config_Manager::create_single_policy: %d\n", + policy_def._d ())); + + CORBA::Policy_var retv; + + switch (policy_def._d ()) + { + case RTCORBA::PRIORITY_MODEL_POLICY_TYPE: + { + const CIAO::DAnCE::PriorityModelPolicyDef &tmp + = policy_def.PriorityModelDef (); + + retv = this->rtorb_->create_priority_model_policy ((RTCORBA::PriorityModel) tmp.priority_model, + tmp.server_priority); + + if (! CORBA::is_nil (retv.in ())) + ACE_DEBUG ((LM_DEBUG, + "Create PriorityModel policy: %d - %d\n", + tmp.priority_model, tmp.server_priority)); + } + break; + + case RTCORBA::THREADPOOL_POLICY_TYPE: + { + RTCORBA::ThreadpoolId tpid = + this->find_threadpool_by_name (policy_def.ThreadpoolDef().Id.in ()); + + retv = this->rtorb_->create_threadpool_policy (tpid); + + if (! CORBA::is_nil (retv.in ())) + ACE_DEBUG ((LM_DEBUG, + "Create Threadpool policy: %s, TPid: %d\n", + policy_def.ThreadpoolDef().Id.in (), tpid)); + } + break; + + case RTCORBA::PRIORITY_BANDED_CONNECTION_POLICY_TYPE: + { + RTCORBA::PriorityBands_var bands = + this->find_priority_bands_by_name (policy_def.PriorityBandedConnectionDef().Id.in ()); + + retv = + this->rtorb_->create_priority_banded_connection_policy (bands.in ()); + + if (! CORBA::is_nil (retv.in ())) + { + ACE_DEBUG ((LM_DEBUG, + "Created Banded Connection policy: %s\n", + policy_def.PriorityBandedConnectionDef().Id.in ())); + } + } + break; + + default: + ACE_ERROR ((LM_ERROR, + "Invalid policy type - RTPolicy_Set_Manager::create_single_policy\n")); + ACE_THROW_RETURN (CORBA::INTERNAL (), 0); + } + + return retv._retn (); +} + diff --git a/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.h b/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.h new file mode 100644 index 00000000000..514a13cb797 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.h @@ -0,0 +1,133 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file RTConfig_Manager.h + * + * $Id$ + * + * This file contains classes that manage name to configuration + * mapping info in a RTComponentServer. + * + * @author Nanbor Wang <nanbor@cs.wustl.edu> + */ +//============================================================================= + + +#ifndef CIAO_RTCONFIG_MANAGER_H +#define CIAO_RTCONFIG_MANAGER_H +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/RTCORBA/RTCORBA.h" +#include "ciao/CIAO_ServerResourcesC.h" +#include "ace/Null_Mutex.h" +#include "ace/SString.h" +#include "ace/Hash_Map_Manager_T.h" + +namespace CIAO +{ + /** + * @brief RTResource_Config_Manager maintains a collection of + * RTCORBA related resources. + * + * This class is responsible to create and manage a list of RTCORBA + * related resources that are global to an RT ComponentServer. The + * information required to create and configure these resources are + * passed in via the @a info argument in the @c init method. These + * resources are identified by names and can be used to associate + * these resources with related RTPolicies. These resources are + * destoryed along with this class. + * + * Currently, the only resources supported (and managed) by this + * class are Threadpool and Threadpool_with_Lanes. + */ + class RTResource_Config_Manager + { + public: + RTResource_Config_Manager (void); + ~RTResource_Config_Manager (void); + + void init (RTCORBA::RTORB_ptr rtorb); + + /// Initializing the RTResource_Config_Manager + void init_resources (const CIAO::DAnCE::ServerResource &info) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Finalizing the RTResource_Config_Manager and the resources it + /// manages. + void fini () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Query a policy set by name + CORBA::PolicyList *find_policies_by_name (const char *name) + ACE_THROW_SPEC ((CORBA::SystemException)); + + protected: + void print_resources (const CIAO::DAnCE::ServerResource &info) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Query a thread pool by name. + RTCORBA::ThreadpoolId find_threadpool_by_name (const char *name) + ACE_THROW_SPEC ((CORBA::SystemException)); + + + /// Query a priority bands info by name. + RTCORBA::PriorityBands *find_priority_bands_by_name (const char *name) + ACE_THROW_SPEC ((CORBA::SystemException)); + + private: + /// Cached an ORB reference. + CORBA::ORB_var orb_; + + // Cached an RTORB reference. + RTCORBA::RTORB_var rtorb_; + + /// Hash_Map stuff. + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + RTCORBA::ThreadpoolId, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> TP_MAP; + + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + RTCORBA::PriorityBands_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> PB_MAP; + + /// Internal TP name to id map. + TP_MAP threadpool_map_; + + /// Internal PB name to priority bands map. + PB_MAP priority_bands_map_; + + /// create a single policy + CORBA::Policy_ptr create_single_policy + (const CIAO::DAnCE::PolicyDef &policy_def) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Hash_Map stuff. + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + CORBA::PolicyList_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> POLICY_MAP; + + /// Internal TP names to id map. + POLICY_MAP policy_map_; + }; +} + +#if defined (__ACE_INLINE__) +# include "RTConfig_Manager.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* CIAO_RTCONFIG_MANAGER_H */ + diff --git a/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.inl b/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.inl new file mode 100644 index 00000000000..9537e7569ac --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/RTConfig_Manager.inl @@ -0,0 +1,13 @@ +// $Id$ + +ACE_INLINE +CIAO::RTResource_Config_Manager::RTResource_Config_Manager () +{ +} + +ACE_INLINE +CIAO::RTResource_Config_Manager::~RTResource_Config_Manager () +{ + this->fini (); +} + diff --git a/modules/CIAO/DAnCE/NodeApplication/RTNA_Configurator_Export.h b/modules/CIAO/DAnCE/NodeApplication/RTNA_Configurator_Export.h new file mode 100644 index 00000000000..5891c5aca0f --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/RTNA_Configurator_Export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl CIAO_RTNA_Configurator +// ------------------------------ +#ifndef CIAO_RTNA_CONFIGURATOR_EXPORT_H +#define CIAO_RTNA_CONFIGURATOR_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (CIAO_RTNA_CONFIGURATOR_HAS_DLL) +# define CIAO_RTNA_CONFIGURATOR_HAS_DLL 1 +#endif /* ! CIAO_RTNA_CONFIGURATOR_HAS_DLL */ + +#if defined (CIAO_RTNA_CONFIGURATOR_HAS_DLL) && (CIAO_RTNA_CONFIGURATOR_HAS_DLL == 1) +# if defined (CIAO_RTNA_CONFIGURATOR_BUILD_DLL) +# define CIAO_RTNA_Configurator_Export ACE_Proper_Export_Flag +# define CIAO_RTNA_CONFIGURATOR_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define CIAO_RTNA_CONFIGURATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* CIAO_RTNA_CONFIGURATOR_BUILD_DLL */ +# define CIAO_RTNA_Configurator_Export ACE_Proper_Import_Flag +# define CIAO_RTNA_CONFIGURATOR_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define CIAO_RTNA_CONFIGURATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* CIAO_RTNA_CONFIGURATOR_BUILD_DLL */ +#else /* CIAO_RTNA_CONFIGURATOR_HAS_DLL == 1 */ +# define CIAO_RTNA_Configurator_Export +# define CIAO_RTNA_CONFIGURATOR_SINGLETON_DECLARATION(T) +# define CIAO_RTNA_CONFIGURATOR_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* CIAO_RTNA_CONFIGURATOR_HAS_DLL == 1 */ + +// Set CIAO_RTNA_CONFIGURATOR_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (CIAO_RTNA_CONFIGURATOR_NTRACE) +# if (ACE_NTRACE == 1) +# define CIAO_RTNA_CONFIGURATOR_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define CIAO_RTNA_CONFIGURATOR_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !CIAO_RTNA_CONFIGURATOR_NTRACE */ + +#if (CIAO_RTNA_CONFIGURATOR_NTRACE == 1) +# define CIAO_RTNA_CONFIGURATOR_TRACE(X) +#else /* (CIAO_RTNA_CONFIGURATOR_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define CIAO_RTNA_CONFIGURATOR_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (CIAO_RTNA_CONFIGURATOR_NTRACE == 1) */ + +#endif /* CIAO_RTNA_CONFIGURATOR_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/NodeApplication/RTNodeApp_Configurator.cpp b/modules/CIAO/DAnCE/NodeApplication/RTNodeApp_Configurator.cpp new file mode 100644 index 00000000000..741d4263188 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/RTNodeApp_Configurator.cpp @@ -0,0 +1,108 @@ +// $Id$ + +#include "RTNodeApp_Configurator.h" +#include "ciao/CIAO_ServerResourcesC.h" +#include "tao/RTPortableServer/RTPortableServer.h" + +CIAO::RTNodeApp_Configurator::~RTNodeApp_Configurator () +{ +} + +int +CIAO::RTNodeApp_Configurator::pre_orb_initialize () +{ + ACE_DEBUG ((LM_DEBUG, "RTNodeApp_Configurator::pre_orb_init\n")); + + return 0; +} + +int +CIAO::RTNodeApp_Configurator::post_orb_initialize (CORBA::ORB_ptr o) +{ + ACE_DEBUG ((LM_DEBUG, "RTNodeApp_Configurator::post_orb_init\n")); + + this->orb_ = CORBA::ORB::_duplicate (o); + + CORBA::Object_var object = + this->orb_->resolve_initial_references ("RTORB"); + + this->rtorb_ = + RTCORBA::RTORB::_narrow (object.in ()); + + this->config_manager_.init (this->rtorb_.in ()); + + return 0; +} + +int +CIAO::RTNodeApp_Configurator::init_resource_manager +(const ::Deployment::Properties &properties) +{ + + // if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG, "RTNodeApp_Configurator::init_resource_manager\n")); + // @@ Should we cache the properties that we consumed here? + + for (CORBA::ULong i = 0; i < properties.length (); ++i) + { + // if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG, "RTNodeApp_Configurator::init_resource_manager processing property: %s\n", + properties[i].name.in ())); + + if (ACE_OS::strcmp ("CIAOServerResources", properties[i].name.in ()) == 0) + { + const CIAO::DAnCE::ServerResource *svr_resource; + if (properties[i].value >>= svr_resource) + { + this->config_manager_.init_resources (*svr_resource); + // Now we have the information to initialize the manager. + } + else + ACE_ERROR_RETURN ((LM_ERROR, + "ERROR: RTNodeApp_Configurator::init_resource_manager unable to extract CIAOServerResources\n"), -1); + } + + // Ignore other stuff + } + + return 0; +} + +CORBA::PolicyList * +CIAO::RTNodeApp_Configurator::find_container_policies +(const ::Deployment::Properties &properties) +{ + ACE_DEBUG ((LM_DEBUG, "RTNodeApp_Configurator::find_container_policies\n")); + // @@ Should we cache the properties that we consumed here? + + for (CORBA::ULong i = 0; i < properties.length (); ++i) + { + ACE_DEBUG ((LM_DEBUG, "RTNodeApp_Configurator::find_container_policies processing property: %s\n", + properties[i].name.in ())); + + if (ACE_OS::strcmp ("ContainerPolicySet", properties[i].name) == 0) + { + const char *policy_name = 0; + if (properties[i].value >>= policy_name) + { + return this->config_manager_.find_policies_by_name (policy_name); + } + else + ACE_ERROR_RETURN ((LM_ERROR, + "ERROR: RTNodeApp_Configurator::find_container_policies unable to extract ContainerPolicySet\n"), 0); + } + } + + return 0; +} + + +extern "C" CIAO_RTNA_Configurator_Export CIAO::NodeApp_Configurator *create_nodeapp_configurator (void); + +CIAO::NodeApp_Configurator * +create_nodeapp_configurator (void) +{ + CIAO::RTNodeApp_Configurator *config = 0; + ACE_NEW_RETURN (config, CIAO::RTNodeApp_Configurator, 0); + return config; +} diff --git a/modules/CIAO/DAnCE/NodeApplication/RTNodeApp_Configurator.h b/modules/CIAO/DAnCE/NodeApplication/RTNodeApp_Configurator.h new file mode 100644 index 00000000000..fc2388b6aff --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplication/RTNodeApp_Configurator.h @@ -0,0 +1,78 @@ +// $Id$ +/**======================================================== + * + * @file RTNodeApp_Configurator.h + * + * @Brief This file contains the implementation of + * the RTNodeApp_Configurator, a concrete NodeApp_Configurator for + * setting up real-time support for NodeApplication. + * + * + * @author Nanbor Wang <nanbor@exothermic.txcorp.com> + *========================================================*/ + +#ifndef RTNODEAPP_CONFIGURATOR_H +#define RTNODEAPP_CONFIGURATOR_H +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "NodeApp_Configurator.h" +#include "RTNA_Configurator_Export.h" +#include "tao/RTCORBA/RTCORBA.h" +#include "RTConfig_Manager.h" + +namespace CIAO +{ + /** + * @class RTNodeApp_Configurator + * + * @brief This class implements a concrete NodeApp_Configurator for + * setting up the NodeApplication process for RT support. + **/ + class CIAO_RTNA_Configurator_Export RTNodeApp_Configurator : + public NodeApp_Configurator + { + public: + /// Default destructor. + virtual ~RTNodeApp_Configurator (void); + + /** + * @brief "pre_orb_initialize" is called before ORB_init. + */ + virtual int pre_orb_initialize (void); + + /** + * @brief "initialize" is called after NodeApplication get a hold + * at this object. + */ + virtual int post_orb_initialize (CORBA::ORB_ptr o); + + /** + * @brief "init_resource_manager" is called by NodeApplication when + * it receives an "install" commands. + */ + virtual int + init_resource_manager (const ::Deployment::Properties &properties); + + /** + * @brief get a policyset by its name. + */ + virtual CORBA::PolicyList * + find_container_policies (const ::Deployment::Properties &properties); + + protected: + CORBA::ORB_var orb_; + + RTCORBA::RTORB_var rtorb_; + + RTResource_Config_Manager config_manager_; + }; +} + +#include /**/ "ace/post.h" +#endif /* RTNODEAPP_CONFIGURATOR_H */ diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/CIAO_NAM_Export.h b/modules/CIAO/DAnCE/NodeApplicationManager/CIAO_NAM_Export.h new file mode 100644 index 00000000000..bdeb544afc4 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/CIAO_NAM_Export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl CIAO_NAM +// ------------------------------ +#ifndef CIAO_NAM_EXPORT_H +#define CIAO_NAM_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (CIAO_NAM_HAS_DLL) +# define CIAO_NAM_HAS_DLL 1 +#endif /* ! CIAO_NAM_HAS_DLL */ + +#if defined (CIAO_NAM_HAS_DLL) && (CIAO_NAM_HAS_DLL == 1) +# if defined (CIAO_NAM_BUILD_DLL) +# define CIAO_NAM_Export ACE_Proper_Export_Flag +# define CIAO_NAM_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define CIAO_NAM_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* CIAO_NAM_BUILD_DLL */ +# define CIAO_NAM_Export ACE_Proper_Import_Flag +# define CIAO_NAM_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define CIAO_NAM_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* CIAO_NAM_BUILD_DLL */ +#else /* CIAO_NAM_HAS_DLL == 1 */ +# define CIAO_NAM_Export +# define CIAO_NAM_SINGLETON_DECLARATION(T) +# define CIAO_NAM_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* CIAO_NAM_HAS_DLL == 1 */ + +// Set CIAO_NAM_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (CIAO_NAM_NTRACE) +# if (ACE_NTRACE == 1) +# define CIAO_NAM_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define CIAO_NAM_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !CIAO_NAM_NTRACE */ + +#if (CIAO_NAM_NTRACE == 1) +# define CIAO_NAM_TRACE(X) +#else /* (CIAO_NAM_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define CIAO_NAM_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (CIAO_NAM_NTRACE == 1) */ + +#endif /* CIAO_NAM_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp b/modules/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp new file mode 100644 index 00000000000..e31a2e6bc91 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp @@ -0,0 +1,651 @@ +// $Id$ + +#include "Containers_Info_Map.h" +#include "ciao/CIAO_Config.h" +#include "ciao/CIAO_common.h" +#include "ciao/CIAO_ServerResourcesC.h" + +//Added for HTTP +#include "URL_Parser.h" //for parsing the URL +#include "tao/HTTP_Client.h" //the HTTP client class to downloading packages +#include "ace/Message_Block.h" //for ACE_Message_Block +#include "ace/OS_NS_fcntl.h" //for open +#include "ace/OS_NS_unistd.h" //for close +#include "ace/OS_NS_sys_stat.h" //for filesize and mkdir +#include "ace/OS_NS_string.h" //for string functions +#include "ace/streams.h" + +namespace CIAO +{ + Containers_Info_Map:: + Containers_Info_Map (const Deployment::DeploymentPlan & plan, + const Deployment::ComponentPlans & shared_components) + : map_ (CIAO_DEFAULT_MAP_SIZE), + plan_ (plan), + shared_components_ (shared_components), + HTTP_DOWNLOAD_PATH () + { + char* temp = ACE_OS::getenv ("CIAO_ROOT"); + HTTP_DOWNLOAD_PATH += temp; + +#if defined (ACE_WIN32) + HTTP_DOWNLOAD_PATH += "\\"; +#else + HTTP_DOWNLOAD_PATH += "/"; +#endif + + HTTP_DOWNLOAD_PATH += "HTTP_DOWNLOADED_LIBS"; + + ACE_OS::mkdir(HTTP_DOWNLOAD_PATH.c_str ()); + //if dir already exists a -1 is returned + //we ignore this, just need to make sure the directory exists + + this->initialize_map (); + this->build_map (); + } + + Deployment::ContainerImplementationInfos * + Containers_Info_Map::containers_info (void) + { + // Fetch the information from the <containers_info_map_> + // and return the corresponding sequence + Deployment::ContainerImplementationInfos_var retv; + + ACE_NEW_RETURN (retv, + Deployment::ContainerImplementationInfos, + 0); + + Iterator end = this->map_.end (); + CORBA::ULong i = 0; + + for (Iterator b = this->map_.begin (); + b != end; + ++b) + { + retv->length (i + 1); + (*retv)[i] = *((*b).int_id_); + + ++i; + } + return retv._retn (); + } + + void + Containers_Info_Map:: + initialize_map (void) + { + const CORBA::ULong instance_len = this->plan_.instance.length (); + + // Iterate over the instance list and look at the policy set id of each + // component instance. For each policy set, we create a separate container + // to host all the components with such policy set. + // NOTE: all the component instances without policies are specified should + // be hosted in the same container, and in our map the key is an empty string "" + for (CORBA::ULong i = 0; i < instance_len; ++i) + { + CORBA::String_var my_resource_id (""); + const char *my_policy_set_id = ""; + + // @@ super hack here. we are assuming RT policy set is + // the only thing that will be specified. + if (this->plan_.instance[i].deployedResource.length () != 0) + { + my_resource_id = + this->plan_.instance[i].deployedResource[0].resourceName.in (); + + this->plan_.instance[i].deployedResource[0].property[0].value >>= + my_policy_set_id; + } + + // If we find a existing policy_set_id, then do nothing. + if (this->map_.find (my_policy_set_id) == 0) + continue; + if (ACE_OS::strcmp (my_policy_set_id, "") == 0) + { + // no policy set id has been specified + Deployment::ContainerImplementationInfo * info; + ACE_NEW (info, Deployment::ContainerImplementationInfo); + this->map_.bind (my_policy_set_id, info); + continue; + } + else + + { + Deployment::ContainerImplementationInfo * info; + ACE_NEW (info, Deployment::ContainerImplementationInfo); + + // Fetch the actual policy_set_def from the infoProperty + // Ugly due to the IDL data structure definition! :( + CORBA::ULong j; + CORBA::ULong infoProperty_length = this->plan_.infoProperty.length (); + bool found = false; + + for (j = 0; j < infoProperty_length; ++j) + { + if (ACE_OS::strcmp (this->plan_.infoProperty[j].name.in (), + "CIAOServerResources") != 0) + continue; + + CIAO::DAnCE::ServerResource *server_resource_def = 0; + this->plan_.infoProperty[j].value >>= server_resource_def; + + if (ACE_OS::strcmp ((*server_resource_def).Id, + my_resource_id.in ()) == 0) + { + // Iterate over the policy_sets + CORBA::ULong k; + CORBA::ULong policy_sets_length = + (*server_resource_def).orb_config.policy_set.length (); + for (k = 0; k < policy_sets_length; ++k) + { + ACE_DEBUG ((LM_DEBUG, "Looking for policy set id: %s\n", my_policy_set_id)); + ACE_DEBUG ((LM_DEBUG, "Compare against policy set id: %s\n\n", + (*server_resource_def).orb_config.policy_set[k].Id.in ())); + + if (ACE_OS::strcmp (my_policy_set_id, + (*server_resource_def).orb_config.policy_set[k].Id) == 0) + { + // Foud the target policy set def + info->container_config.length (1); + info->container_config[0].name = + CORBA::string_dup ("ContainerPolicySet"); + info->container_config[0].value <<= + my_policy_set_id; + // (*server_resource_def).orb_config.policy_set[k]; + + ACE_DEBUG ((LM_DEBUG, "Found matching rt policy set*****\n\n")); + found = true; + break; + } + } + if (k == policy_sets_length) + { + // No Server Resource Def found? + ACE_DEBUG ((LM_DEBUG, + "No matching policy set def found in resource def: %s!\n", + my_resource_id.in ())); + } + } + + // if we successfully found the policy_set_id + if (found) + break; + } // end of for loop for fetching policy_set_def + + if (j == this->plan_.infoProperty.length ()) + { + // No Server Resource Def found?! Inconsistent descriptor files. + ACE_ERROR ((LM_ERROR, "(%P|%t) Descriptor error: " + "No matching server resource def found for component: %s!\n", + this->plan_.instance[i].name.in ())); + } + else + this->map_.bind (my_policy_set_id, info); + } + } + } + + bool + Containers_Info_Map:: + build_map (void) + { + const CORBA::ULong instance_len = this->plan_.instance.length (); + + for (CORBA::ULong i = 0; i < instance_len; ++i) + { + const Deployment::InstanceDeploymentDescription & instance = + this->plan_.instance[i]; + + // If this component instance happens to be in the "shared components + // list", then we ignore it, otherwise we shall install it. + ACE_CString name (instance.name.in ()); + if (this->is_shared_component (name)) + continue; + + if (! this->insert_instance_into_map (instance)) + return false; + } + + return true; + } + + bool + Containers_Info_Map::insert_instance_into_map ( + const Deployment::InstanceDeploymentDescription & instance) + { + Deployment::ContainerImplementationInfo container_info; + + const char * policy_set_id = ""; + if (instance.deployedResource.length () != 0) + { + instance.deployedResource[0].property[0].value >>= policy_set_id; + // instance.deployedResource[0].resourceValue >>= policy_set_id; + //ACE_ERROR ((LM_ERROR, "ERROR: RT-CCM support has been disabled until code in Containers_Info_Map is updated to reflect IDL changes.")); + } + + // Find the ContainerImplementationInfo entry from the map + MAP::ENTRY *entry = 0; + if (this->map_.find (policy_set_id, entry) != 0) + return false; //should never happen + else + { + this->insert_instance_into_container ( + instance, + entry->int_id_->impl_infos); + } + + return true; + } + + bool + Containers_Info_Map::insert_instance_into_container ( + const Deployment::InstanceDeploymentDescription & instance, + Deployment::ComponentImplementationInfos & impl_infos) + { + // Increase the length of the ComponentImplementationInfos by one + CORBA::ULong i = impl_infos.length (); + impl_infos.length (i + 1); + + // Fill in the information about this component instance + // Get the component instance name. + impl_infos[i].component_instance_name = instance.name.in (); + + const Deployment::MonolithicDeploymentDescription & impl = + this->plan_.implementation[instance.implementationRef]; + + const CORBA::ULong artifact_num = impl.artifactRef.length (); + + // Copy Component instance related Properties if there is any. + if (instance.configProperty.length () > 0) + { + impl_infos[i].component_config = instance.configProperty; + } + + bool svnt_found = false; + bool exec_found = false; + + // For svnt/exec artifacts + for (CORBA::ULong j = 0; j < artifact_num; ++j) + { + Deployment::ArtifactDeploymentDescription arti = + this->plan_.artifact[ impl.artifactRef[j] ]; + + for (size_t loc_num = 0; + loc_num < arti.location.length (); + ++loc_num) + { + if (ACE_OS::strstr (arti.location[loc_num], "http://")) + { + ACE_CString path; + ACE_CString arti_name; + if (!this->resolve_http_reference (arti.location[loc_num], + arti_name, + path)) + { + ACE_ERROR + ((LM_ERROR, + "CIAO (%P|%t) Containers_Info_Map.cpp -" + "Containers_Info_Map::insert_instance_into_container -" + "ERROR: Unable to resolve HTTP ref to location[%d] of %s\n", + loc_num, arti.name.in ())); + + //No need to throw an exception here! + //Actually it is not desirable. + //This is handled in a different part of DAnCE + arti.location[loc_num] = "HTTP_failure"; + } + else + { + arti.location[loc_num] = arti_name.c_str (); + //enque for cleanup + } + } + } + + ACE_CString tmp = arti.name.in (); + ACE_CString::size_type pos; + + //@@ Note: I am not checking for redundancy here. Maybe + // the modeling tool should make sure of + // uniqueness, i.e., one component implementation + // should have only 1 _svnt and 1 _exec libs. + if ((pos = tmp.find ("_stub")) != ACE_CString::npos || + (pos = tmp.find ("_Stub")) != ACE_CString::npos) + continue; // We ignore _stub artifact since it's not used. + + if (!svnt_found && + ((pos = tmp.find ("_svnt")) != ACE_CString::npos || + (pos = tmp.find ("_Svnt")) != ACE_CString::npos)) + { + if (arti.location.length() < 1 ) + { + ACE_DEBUG ((LM_DEBUG, "Servant Artifact must have a location!\n")); + return 0; + } + + svnt_found = true; + // Copy the servant dll/so name. + // @@ Note: I ignore all the other locations except the first one. + impl_infos[i].servant_dll = + CORBA::string_dup (arti.location[0]); + + // Get the entry point. + const CORBA::ULong prop_length = arti.execParameter.length (); + + for (CORBA::ULong prop_num = 0; + prop_num < prop_length; + ++prop_num) + { + ACE_CString name (arti.execParameter[prop_num].name.in ()); + if (name == ACE_CString ("entryPoint")) + { + const char * entry = 0; + (arti.execParameter[prop_num].value) >>= entry; + impl_infos[i].servant_entrypt = CORBA::string_dup (entry); + } + else + { + ACE_DEBUG ((LM_DEBUG, "Found unknown property in the artifact!\n")); + ACE_DEBUG ((LM_DEBUG, "We only support entrypoint at this point in CIAO.\n")); + } + } + + continue; // continue for the next artifact + } + + // As one can see, code is duplicated here. I will come back for this later. + // For exec artifact + if (!exec_found && + ((pos = tmp.find ("_exec")) != ACE_CString::npos || + (pos = tmp.find ("_Exec")) != ACE_CString::npos)) + { + if (arti.location.length() < 1 ) + { + ACE_DEBUG ((LM_DEBUG, "Executor Artifact must have a location!\n")); + return 0; + } + + exec_found = true; + // Copy the servant dll/so name. + // @@ Note: I ignore all the other locations except the first one. + exec_found = true; + impl_infos[i].executor_dll = + CORBA::string_dup (arti.location[0]); + + // Get the entry point. + const CORBA::ULong prop_length = arti.execParameter.length (); + for (CORBA::ULong prop_num = 0; + prop_num < prop_length; + ++prop_num) + { + ACE_CString name (arti.execParameter[prop_num].name.in ()); + if (name == ACE_CString ("entryPoint")) + { + const char * entry = 0; + (arti.execParameter[prop_num].value) >>= entry; + impl_infos[i].executor_entrypt = CORBA::string_dup (entry); + } + else + { + ACE_DEBUG ((LM_DEBUG, "Found unknown property in the artifact!\n")); + ACE_DEBUG ((LM_DEBUG, "We only support entrypoint at this point in CIAO.\n")); + } + } + } + else + // We see artifact other than servant/executor and we ignore them. + continue; + } + return true; + } +} + +bool +CIAO::Containers_Info_Map:: +is_shared_component (ACE_CString & name) +{ + for (CORBA::ULong i = 0; i < this->shared_components_.length (); ++i) + { + if (ACE_OS::strcmp (this->shared_components_[i].name.in (), + name.c_str ()) == 0) + return true; + } + + return false; +} + + +/*--------------------------------------------------------------------- + * functions to support HTTP capabilities of the NodeApplicationManager + * @author Stoyan Paunov + * + * Purpose: Adding the HTTP access code which will resove + * any references to HTTP URLs + */ + + // This function checks if the HTTP_DOWNLOAD_PATH is + // in the library load path + void + CIAO::Containers_Info_Map::update_loader_path (void) + { +#if defined (ACE_WIN32) + char* path = ACE_OS::getenv ("PATH"); +#else + char* path = ACE_OS::getenv ("LD_LIBRARY_PATH"); +#endif + + if (ACE_OS::strstr (path, this->HTTP_DOWNLOAD_PATH.c_str ())) + return; + +#if defined (ACE_WIN32) + ACE_CString new_path = "PATH="; +#else + ACE_CString new_path = "LD_LIBRARY_PATH="; +#endif + + new_path += this->HTTP_DOWNLOAD_PATH; + +#if defined (ACE_WIN32) + new_path += ";"; +#else + new_path += ":"; +#endif + + new_path += path; + + ACE_OS::putenv (new_path.c_str ()); + + } + + //This function resolves any http location references + //in the name of the implementation artifacts + //It returns true on success and false on failure + + bool + CIAO::Containers_Info_Map::resolve_http_reference (const char* location, + ACE_CString &arti_name, + ACE_CString &path) + { + // Figure out the file name. + char* name = const_cast<char*> (location); + char* p = 0; + + while (true) + { + p = ACE_OS::strstr (name, "/"); + + if (0 == p) + { + p = ACE_OS::strstr (name, "\\"); + } + + if (0 == p) + { + break; + } + else + { + name = ++p; + continue; + } + } + + arti_name = name; + + // Get the file. + ACE_Message_Block* mb = 0; + ACE_NEW_RETURN (mb, ACE_Message_Block (0,0), false); + + if (!this->retrieve_via_HTTP (location, *mb)) + { + mb->release (); + return false; + } + +#if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK) + ACE_TString decorator (ACE_LD_DECORATOR_STR); +#endif + ACE_TString prefix (ACE_DLL_PREFIX); + ACE_TString suffix (ACE_DLL_SUFFIX); + + ACE_CString new_name (name); + new_name = prefix + new_name; +#if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK) + new_name += decorator; +#endif + new_name += suffix; + + path = HTTP_DOWNLOAD_PATH; + path += "/"; + path += new_name; + + if (!this->write_to_disk (path.c_str (), *mb)) + { + mb->release (); + return false; + } + + mb->release (); + return true; + } + + //function to retvieve a file via HTTP + //stores the file in the passed preallocated ACE_Message_Block + //returns 1 on success + // 0 on error + + bool + CIAO::Containers_Info_Map::retrieve_via_HTTP (const char* URL, + ACE_Message_Block &mb) + { + ACE_CString loc (URL); + + // Figure out the file name. + char* name_ = const_cast<char*> (URL); + char* p = 0; + + while (true) + { + p = ACE_OS::strstr (name_, "/"); + + if (0 == p) + { + p = ACE_OS::strstr (name_, "\\"); + } + + if (0 == p) + { + break; + } + else + { + name_ = ++p; + continue; + } + } + + ACE_CString name (name_); + loc = loc.substr (0, loc.length() - name.length ()); + +#if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK) + ACE_TString decorator (ACE_LD_DECORATOR_STR); +#endif + ACE_TString prefix (ACE_DLL_PREFIX); + ACE_TString suffix (ACE_DLL_SUFFIX); + + ACE_CString new_name (name); + new_name = prefix + new_name; +#if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK) + new_name += decorator; +#endif + new_name += suffix; + + loc = loc + new_name; + + ACE_DEBUG ((LM_INFO, + "Attempting to download %s\n", + loc.c_str ())); + + URL_Parser *parser = TheURL_Parser::instance (); + if (!parser->parseURL (const_cast<char*> (loc.c_str ()))) + return false; + + // Create a client + TAO_HTTP_Client client; + + // Open the client + if (client.open (parser->filename_, + parser->hostname_, + parser->port_) == -1) + { + client.close (); + return false; + } + + // Read from it + if (client.read (&mb) <= 0) + { + client.close (); + return false; + } + + return true; + } + + //This function attempts to write a sequence of bytes from an + //ACE_Message_Block to a specified location. A 0 is returned + //in the case of an error and a 1 upon success + + bool + CIAO::Containers_Info_Map::write_to_disk (const char* full_path, + ACE_Message_Block& mb, + bool replace) + { + ACE_stat stat; + + if (ACE_OS::stat(full_path, &stat) != -1 && !replace) + return false; + + // Open a file handle to the local filesystem + ACE_HANDLE handle = ACE_OS::open (full_path, O_CREAT | O_TRUNC | O_WRONLY); + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[CIAO::Containers_Info_Map::write_to_disk]"), + ACE_TEXT (" file creation error")), + false); + + //write the data to the file + for (ACE_Message_Block * curr = &mb; curr != 0; curr = curr->cont ()) + if (ACE_OS::write_n (handle, curr->rd_ptr(), curr->length()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[CIAO::Containers_Info_Map::write_to_disk]"), + ACE_TEXT (" write error")), + false); + + // Close the file handle + ACE_OS::close (handle); + + return true; + } diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.h b/modules/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.h new file mode 100644 index 00000000000..93f6b70c5cc --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.h @@ -0,0 +1,137 @@ +/** + * + * @file Containers_Info_Map.h + * @author Gan Deng <dengg@dre.vanderbilt.edu> + * + * Map of ContainerImplementationInfo sequences. + * + * $Id$ + */ + +#ifndef CIAO_CONTAINERS_INFO_MAP_H +#define CIAO_CONTAINERS_INFO_MAP_H + +#include /**/ "ace/pre.h" + +#include "ace/Null_Mutex.h" +#include "ace/Hash_Map_Manager.h" + +//added for the HTTP support +#include "ace/Message_Block.h" //for ACE_Message_Block + +#include "ciao/Deployment_ContainerC.h" +#include "ciao/DeploymentC.h" +#include "ace/SString.h" +#include "CIAO_NAM_Export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace CIAO +{ + /** + * @class Container_Infos_Map + * @brief Implementation of a map of ContainerImplementationInfo sequences. + * + * This is a helper class to populate the NodeImplementationInfo struct from + * a deployment plan.. + */ + class CIAO_NAM_Export Containers_Info_Map + { + public: + + Containers_Info_Map (const Deployment::DeploymentPlan & plan, + const Deployment::ComponentPlans & shared_components); + + Deployment::ContainerImplementationInfos * + containers_info (void); + + private: + void initialize_map (void); + bool build_map (void); + + bool insert_instance_into_map ( + const Deployment::InstanceDeploymentDescription & instance); + + bool insert_instance_into_container ( + const Deployment::InstanceDeploymentDescription & instance, + Deployment::ComponentImplementationInfos & impl_infos); + + /// Helper function to check wheather a component instance + /// is in the "shared components list". + bool is_shared_component (ACE_CString & name); + + //Deployment::ContainerImplementationInfos_var containers_info_; + + typedef + ACE_Hash_Map_Manager_Ex <ACE_CString, + Deployment::ContainerImplementationInfo *, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> MAP; + + typedef MAP::iterator Iterator; + MAP map_; + + const Deployment::DeploymentPlan & plan_; + + /// shared components list, passed in from NodeImplementationInfoHandler + /// class. + Deployment::ComponentPlans shared_components_; + + /**------------------------------------------------------------------- + * HTTP capability + * @author Stoyan Paunov + * + * Purpose: Adding the HTTP access code which will resove + * any references to HTTP URLs + */ + protected: + + // @Stoyan - Please follow ACE coding guideines when naming your + //member variables. In particular, please use lower case and + //follow the name with a trailing underscore. + //directory in which to download the libraries obtained via HTTP + ACE_CString HTTP_DOWNLOAD_PATH; + + /// This function checks if the HTTP_DOWNLOAD_PATH is + /// in the library load path + void + update_loader_path (void); + + /// This function resolves any http location references + /// in the name of the implementation artifacts + /// It returns true on success and false on failure + bool + resolve_http_reference (const char* location, + ACE_CString &arti_name, + ACE_CString &name); + + /// function to retvieve a file via HTTP + /// stores the file in the passed preallocated ACE_Message_Block + /// returns 1 on success + /// 0 on error + bool + retrieve_via_HTTP (const char* URL, + ACE_Message_Block &mb); + + /// function that writes out a file to a specified location on the hand disk + /// returns 1 on success + /// 0 on already exists and replace == false + /// 0 on error + + bool + write_to_disk (const char* full_path, + ACE_Message_Block& mb, + bool replace = true); + + /// TODO: Fuction to remove the downloaded library to ensure + /// consisterncy in future runs + + }; +} + +#include /**/ "ace/post.h" + +#endif /*CIAO_CONTAINERS_INFO_MAP_H*/ diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/ImplementationInfo.cpp b/modules/CIAO/DAnCE/NodeApplicationManager/ImplementationInfo.cpp new file mode 100644 index 00000000000..af905369dcf --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/ImplementationInfo.cpp @@ -0,0 +1,95 @@ +//$Id$ +#ifndef CIAO_IMPLEMENTATION_INFO_CPP +#define CIAO_IMPLEMENTATION_INFO_CPP + +#include "ImplementationInfo.h" +#include "ciao/CIAO_ServerResourcesC.h" +#include "ace/SString.h" + +CIAO::NodeImplementationInfoHandler:: +NodeImplementationInfoHandler (const ::Deployment::DeploymentPlan & plan, + const Deployment::ComponentPlans & shared_components) : + plan_ (plan), + node_info_ (0), + containers_info_map_ (plan, shared_components) +{ + ACE_NEW (node_info_, ::Deployment::NodeImplementationInfo); + this->populate_server_resource_def (); + this->populate_container_impl_infos (); +} + +Deployment::NodeImplementationInfo * +CIAO::NodeImplementationInfoHandler::node_impl_info (void) const +{ + Deployment::NodeImplementationInfo_var retv; + ACE_NEW_RETURN (retv, + Deployment::NodeImplementationInfo (this->node_info_.in ()), + 0); + return retv._retn (); +} + +void +CIAO::NodeImplementationInfoHandler::populate_server_resource_def (void) +{ + CORBA::ULong const instance_len = plan_.instance.length (); + const char * target_resource_id = 0; + + // Iterate over the instance list to find whether any server resource + // has been specified + // TODO: We shoud do some sanity check here, since all the component + // instance in this NodeApplication should have the same "server_resource_def" + // defined. Since currently we ignored this sanity check, then will allow + // users to specify some self-conflicting configuration in the descriptor. + + // NW: this stuff is broken because it assumes all component + // instances in a node will use the same ServerResource file. This + // is not the case. Component instances using the same + // ServerResource file will be deployed in the same NA. However, + // those using different ServerResource files should be deployed to + // different NAs. Something to be fixed later. + for (CORBA::ULong i = 0; i < instance_len; ++i) + { + if (this->plan_.instance[i].deployedResource.length () != 0) + { + target_resource_id = + this->plan_.instance[i].deployedResource[0].resourceName.in (); + + // Some component instance has server resource usage defined, so we + // set the <nodeapp_config> field of the NodeImplementationInfo struct. + for (CORBA::ULong j = 0; j < this->plan_.infoProperty.length (); ++j) + { + CIAO::DAnCE::ServerResource *server_resource_def = 0; + this->plan_.infoProperty[j].value >>= server_resource_def; + + if (ACE_OS::strcmp ((*server_resource_def).Id, + target_resource_id) == 0) + { + // Found the target server resource def, and store it. + this->node_info_->nodeapp_config.length (1); + + this->node_info_->nodeapp_config[0].name = + CORBA::string_dup ("CIAOServerResources"); + + this->node_info_->nodeapp_config[0].value <<= + *server_resource_def; + break; + } + } + } + } +} + +void +CIAO::NodeImplementationInfoHandler::populate_container_impl_infos (void) +{ + CORBA::ULong const curr_len = + this->containers_info_map_.containers_info ()->length (); + + ACE_UNUSED_ARG (curr_len); + + // assignment operation + this->node_info_->impl_infos = + *(this->containers_info_map_.containers_info ()); +} + +#endif /* CIAO_IMPLEMENTATION_INFO_CPP */ diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/ImplementationInfo.h b/modules/CIAO/DAnCE/NodeApplicationManager/ImplementationInfo.h new file mode 100644 index 00000000000..2b935d9d637 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/ImplementationInfo.h @@ -0,0 +1,60 @@ +//$Id$ +/* -*- C++ -*- */ +/*************************************************************** + * @file ImplementationInfo.h + * + * @brief This file defines some helper functions for preparing the + * Component ImplementationInfo and properties from + * the plan. + * + * @author Tao Lu <lu@dre.vanderbilt.edu> + * @author Gan Deng <dengg@dre.vanderbilt.edu> + ***************************************************************/ + +#ifndef IMPLEMENTATIONIFO_H +#define IMPLEMENTATIONIFO_H +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ciao/Deployment_NodeApplicationC.h" +#include "ace/SString.h" +#include "ace/Hash_Map_Manager.h" +#include "Containers_Info_Map.h" +#include "CIAO_NAM_Export.h" + +namespace CIAO +{ + /// This class is a helper class to parse the local deployment plan into the + /// NodeImplementationInfo struct. + class CIAO_NAM_Export NodeImplementationInfoHandler + { + public: + NodeImplementationInfoHandler ( + const ::Deployment::DeploymentPlan & plan, + const Deployment::ComponentPlans & shared_components); + + Deployment::NodeImplementationInfo * + node_impl_info (void) const; + + private: + Deployment::DeploymentPlan plan_; + + Deployment::NodeImplementationInfo_var node_info_; + + void populate_server_resource_def (void); + + void populate_container_impl_infos (void); + + /// Helper class that helps populate the container_impl_infos + /// field. + Containers_Info_Map containers_info_map_; + }; +} + +#include /**/ "ace/post.h" +#endif /* IMPLEMENTATIONIFO_H */ diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager.mpc b/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager.mpc new file mode 100644 index 00000000000..a145a6f09f2 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager.mpc @@ -0,0 +1,24 @@ +// -*- MPC -*- +// $Id$ + +project(NodeApplicationManager): ciao_server_dnc, ciao_deployment_svnt, dance_extension_stub, ciao_nodeapplication { + + sharedname = NodeApplicationManager + after += NodeManager_stub CIAO_TargetManager_stub + dynamicflags = CIAO_NAM_BUILD_DLL + + Source_Files { + NodeApplicationManager_Impl.cpp + ImplementationInfo.cpp + Containers_Info_Map.cpp + URL_Parser.cpp + } + + Header_Files { + NodeApplicationManager_Impl.h + ImplementationInfo.h + Containers_Info_Map.h + URL_Parser.h + CIAO_NAM_Export.h + } +} diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.cpp b/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.cpp new file mode 100644 index 00000000000..51f6cbdb50e --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.cpp @@ -0,0 +1,1161 @@ +// $Id$ + +#include "NodeApplicationManager_Impl.h" +#include "ace/Process.h" +#include "ace/Process_Manager.h" +#include "ace/Reactor.h" +#include "ace/OS_NS_stdio.h" +#include "ace/Sched_Params.h" +#include "ace/Vector_T.h" +#include "ciao/Container_Base.h" +#include "ciao/CIAO_ServerResourcesC.h" +#include "NodeApplication/NodeApplication_Impl.h" +#include "ace/Reactor.h" + +#if !defined (__ACE_INLINE__) +# include "NodeApplicationManager_Impl.inl" +#endif /* __ACE_INLINE__ */ + + +bool +CIAO::NodeApplicationManager_Impl_Base:: +is_shared_component (ACE_CString & name) +{ + for (CORBA::ULong i = 0; i < this->shared_components_.length (); ++i) + { + if (ACE_OS::strcmp (this->shared_components_[i].name.in (), + name.c_str ()) == 0) + return true; + } + + return false; +} + +bool +CIAO::NodeApplicationManager_Impl_Base:: +is_external_component (ACE_CString & name) +{ + for (CORBA::ULong i = 0; i < this->external_components_.length (); ++i) + { + if (ACE_OS::strcmp (this->external_components_[i].name.in (), + name.c_str ()) == 0 && + ACE_OS::strcmp (this->external_components_[i].plan_uuid.in (), + this->plan_.UUID.in ())) + return true; + } + + return false; +} + +Deployment::Connections * +CIAO::NodeApplicationManager_Impl_Base:: +create_connections () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty)) +{ + CIAO_TRACE("CIAO::NodeApplicationManager_Impl::create_connections"); + Deployment::Connections_var retv; + + ACE_NEW_THROW_EX (retv, + Deployment::Connections (), + CORBA::NO_MEMORY ()); + + CORBA::ULong len = retv->length (); + + const Component_Iterator end (this->component_map_.end ()); + for (Component_Iterator iter (this->component_map_.begin ()); + iter != end; + ++iter) + { + // If this component is in the "shared components list", then we + // should just simply fetch the port object references from the + // NodeManager. + ACE_CString comp_name ((*iter).ext_id_.c_str ()); + + // Get all the facets first + Components::FacetDescriptions_var facets; + + if (this->is_shared_component (comp_name)) + { + ACE_DEBUG ((LM_DEBUG, "NAMImpl::create_connections: Component %s is shared\n", + comp_name.c_str ())); + facets = this->node_manager_->get_all_facets (comp_name); + } + else + { + ACE_DEBUG ((LM_DEBUG, "NAMImpl::create_connections: Component %s is not shared, getting and setting " + "all facets\n", + comp_name.c_str ())); + facets = ((*iter).int_id_)->get_all_facets (); + this->node_manager_->set_all_facets (comp_name, facets); + } + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "DAnCE (%P|%t) NodeApplicationManager_Impl.cpp -" + "CIAO::NodeApplicationManager_Impl::create_connections -" + "success getting facets for the component " + "instance [%s] \n", + comp_name.c_str ())); + } + + // Get all the event consumers + Components::ConsumerDescriptions_var consumers; + + if (this->is_shared_component (comp_name)) + { + ACE_DEBUG ((LM_DEBUG, "NAMImpl::create_connections: Component %s is shared\n", + comp_name.c_str ())); + consumers = this->node_manager_->get_all_consumers (comp_name); + } + else + { + ACE_DEBUG ((LM_DEBUG, "NAMImpl::create_connections: Component %s is not shared, getting and setting " + "all facets\n", + comp_name.c_str ())); + consumers = + ((*iter).int_id_)->get_all_consumers (); + this->node_manager_->set_all_consumers (comp_name, consumers); + } + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "DAnCE (%P|%t) NodeApplicationManager_Impl.cpp -" + "CIAO::NodeApplicationManager_Impl::create_connections -" + "success getting consumers for the component " + "instance [%s] \n", + comp_name.c_str ())); + } + + CORBA::ULong const facet_len = facets->length (); + CORBA::ULong const consumer_len = consumers->length (); + + CORBA::ULong const curr_len = retv->length (); + retv->length (curr_len + facet_len + consumer_len); + + CORBA::ULong i = 0; + for (i = 0; i < facet_len; ++i) + { + Deployment::Connection & conn = retv[len]; + conn.instanceName = (*iter).ext_id_.c_str (); + conn.portName = facets[i]->name (); + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "DAnCE (%P|%t) NodeApplicationManager_Impl.cpp -" + "CIAO::NodeApplicationManager_Impl::create_connections -" + "adding connection for facet [%s] in instance [%s] \n", + conn.portName.in (), conn.instanceName.in ())); + } + conn.kind = Deployment::Facet; + conn.endpoint = CORBA::Object::_duplicate (facets[i]->facet_ref ()); + ++len; + } + + for (i = 0; i < consumer_len; ++i) + { + Deployment::Connection & conn = retv[len]; + conn.instanceName = (*iter).ext_id_.c_str (); + conn.portName = consumers[i]->name (); + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "DAnCE (%P|%t) NodeApplicationManager_Impl.cpp -" + "CIAO::NodeApplicationManager_Impl::create_connections -" + "adding connection for consumer [%s] in instance [%s] \n", + conn.portName.in (), conn.instanceName.in ())); + } + conn.kind = Deployment::EventConsumer; + conn.endpoint = CORBA::Object::_duplicate (consumers[i]->consumer ()); + ++len; + } + } + return retv._retn (); +} + +Deployment::Application_ptr +CIAO::NodeApplicationManager_Impl_Base:: +startLaunch (const Deployment::Properties & configProperty, + Deployment::Connections_out providedReference, + CORBA::Boolean start) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty)) +{ + try + { + CIAO_TRACE("CIAO::NodeApplicationManager_Impl::startLaunch"); + ACE_UNUSED_ARG (configProperty); + ACE_UNUSED_ARG (start); + + // In this step, we know all the "shared components" are + // the external components to ourself. + this->external_components_ = this->shared_components_; + + // If no additional components need to be installed, then we simply + // create a NA, but doesn't install any components on it. + if (this->plan_.instance.length () == this->shared_components_.length ()) + { + ACE_DEBUG ((LM_DEBUG, "Prespawn a NodeApplication process without " + "installing any components.\n")); + } + + /** + * 1. First Map properties to TAO/CIAO specific property/configurations + * 2. Necessary property checking (needed?) + * 3. Call create_nade_application to spawn new process. + * 4. Initialize the NodeApplication. + * 5. get the provided connection endpoints back and return them. + */ + + NodeImplementationInfoHandler handler (this->plan_, this->shared_components_); + + Deployment::NodeImplementationInfo * node_info = + handler.node_impl_info (); + + if (!node_info) + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) NodeApplicationManager.cpp -" + "CIAO::NodeApplicationManager_Impl::startLaunch -" + "Failed to create Node Implementation Infos!\n")); + + throw + (Deployment::StartError ("NodeApplicationManager_Imp::startLaunch", + "Unable to get node level infos")); + } + + CIAO::DAnCE::ServerResource *server_resource = 0; + for (CORBA::ULong k = 0; k < node_info->nodeapp_config.length (); ++k) + { + if (ACE_OS::strcmp (node_info->nodeapp_config[k].name.in (), + "CIAOServerResources") == 0) + { + node_info->nodeapp_config[0].value >>= server_resource; + break; // Ignore the rest of the NodeApp_Config values + } + } + + // Now spawn the NodeApplication process. + // @@TODO: we need to pass arguments to the nodeapplication, ie + // naming service endpoints, if necessary + // (will) + ACE_CString cmd_option (this->nodeapp_command_op_.in ()); + + if (server_resource) + { + // If command line options are specified through RTCCM descriptors, + // then we should honor these command line options as well. + for (CORBA::ULong arg_i = 0; + arg_i < (*server_resource).args.length (); + ++arg_i) + { + cmd_option += " "; // space between command line args + cmd_option += (*server_resource).args[arg_i]; + } + + // If service configuration file is specified through RTCCM + // descriptors, then we should honor it as well. + if (ACE_OS::strcmp ((*server_resource).svcconf.in (), + "") != 0) + { + cmd_option += " -ORBSvcConf "; + cmd_option += (*server_resource).svcconf; + } + } + + Deployment::NodeApplication_var tmp = + create_node_application (cmd_option.c_str ()); + + if (CIAO::debug_level () > 9) + { + CORBA::ULong curr_len = node_info->impl_infos.length (); + ACE_UNUSED_ARG (curr_len); + + Deployment::ComponentImplementationInfos infos = + ((node_info->impl_infos)[0]).impl_infos; + + const CORBA::ULong info_len = infos.length (); + for (CORBA::ULong i = 0; i < info_len; ++i) + { + ACE_DEBUG ((LM_DEBUG, + "DAnCE (%P|%t) NodeApplicationManager.cpp -" + "CIAO::NodeApplicationManager_Impl::startLaunch -" + "The info for installation: " + "\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", + infos[i].component_instance_name.in (), + infos[i].executor_dll.in (), + infos[i].executor_entrypt.in (), + infos[i].servant_dll.in (), + infos[i].servant_entrypt.in () )); + } + } + + // This is what we will get back, a sequence of component object refs. + Deployment::ComponentInfos_var comp_info; + + // This will install all homes and components. + comp_info = this->nodeapp_->install (*node_info); + + + // Now fill in the map we have for the "newly installed" components. + const CORBA::ULong comp_len = comp_info->length (); + for (CORBA::ULong len = 0; + len < comp_len; + ++len) + { + //Since we know the type ahead of time...narrow is omitted here. + if (this->component_map_. + bind (comp_info[len].component_instance_name.in(), + Components::CCMObject::_duplicate + (comp_info[len].component_ref.in()))) + { + ACE_CString error ("Duplicate component instance name "); + error += comp_info[len].component_instance_name.in(); + + throw + (Deployment::StartError + ("NodeApplicationManager_Impl::startLaunch", + error.c_str ())); + } + } + + // Also, we need to fill in the map about those "shared components" + // For now, we could use "NIL" component object reference for these + // shared components since they are not used anyway. + CORBA::ULong shared_comp_length = this->shared_components_.length (); + for (CORBA::ULong j = 0; j < shared_comp_length; ++j) + { + if (this->component_map_. + bind (this->shared_components_[j].name.in (), + Components::CCMObject::_nil ())) + { + ACE_CString error ("Duplicate component instance name "); + error += this->shared_components_[j].name.in(); + + throw + (Deployment::StartError + ("NodeApplicationManager_Impl::startLaunch", + error.c_str ())); + } + } + + + providedReference = + this->create_connections (); + + if (providedReference == 0) + { + throw + (Deployment::StartError + ("NodeApplicationManager_Impl::startLaunch", + "Error creating connections for components during startLaunch.")); + } + } + catch (const Deployment::UnknownImplId& e) + { + ACE_THROW_RETURN (Deployment::StartError (e.name.in (), + e.reason.in ()), + Deployment::Application::_nil()); + } + catch (const Deployment::ImplEntryPointNotFound& e) + { + ACE_THROW_RETURN (Deployment::StartError (e.name.in (), + e.reason.in ()), + Deployment::Application::_nil()); + } + catch (const Deployment::InstallationFailure& e) + { + ACE_THROW_RETURN (Deployment::StartError (e.name.in (), + e.reason.in ()), + Deployment::Application::_nil()); + } + + return Deployment::NodeApplication::_duplicate (this->nodeapp_.in ()); +} + + +Deployment::Application_ptr +CIAO::NodeApplicationManager_Impl_Base:: +perform_redeployment (const Deployment::Properties & configProperty, + Deployment::Connections_out providedReference, + CORBA::Boolean /*add_or_remove*/, // true means "add" only + CORBA::Boolean start) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::PlanError, + ::Deployment::InstallationFailure, + ::Deployment::UnknownImplId, + ::Deployment::ImplEntryPointNotFound, + ::Deployment::InvalidConnection, + ::Deployment::InvalidProperty, + ::Components::RemoveFailure)) +{ + // Prerequisite: + // (1) If this is an existiing old NAM, then <nodeapp_> is ready to use. + // We also got a copy of <plan_> as well as all the installed components + // in the <component_map_>. + // (2) Then we should call <install> operation on the NA, but in order to do this, + // we must pack all the to-be-added components into some appropriate + // data structure called "NodeImplementationInfo". + // (3) We should also call <remove> operation on the NA to remove those + // to-be-removed components, and the "comp_inst_name" could be as input. + // (4) We should also consider removing all the unneeded "connections", but + // this should be driven by the DAM, so it looks like that we need to + // add another operation on the NA interface which is a counterpart of + // <finishLaunch>, something like <finishLaunch_remove_only>. + // + // + // + // (1) If this is an brand new NAM, then only new installation is needed. + // (2) Then we could pretty much replicate the "startLaunch" implementation. + // This capability is useful to install a set of new components into + // some totally new nodes. + + ACE_UNUSED_ARG (configProperty); + ACE_UNUSED_ARG (start); + + CIAO_TRACE ("CIAO::NodeApplicationManager_Impl_Base::perform_redeployment"); + + ACE_DEBUG ((LM_DEBUG, + "CIAO (%P|%t) NodeApplicationManager_Impl_Base: " + "invoked CIAO::NodeApplicationManager_Impl_Base::perform_redeployment \n")); + try + { + if (! CORBA::is_nil (this->nodeapp_.in ())) + { + // We ignored those components that are already in the <component_map_>, for + // the rest ones, we pack them into NodeImplementationInfo. + Deployment::DeploymentPlan tmp_plan = this->plan_; + tmp_plan.instance.length (0); + + CORBA::ULong const length = this->plan_.instance.length (); + for (CORBA::ULong i = 0; i < length; ++i) + { + // add the new components into the tmp_plan + if (this->component_map_.find (this->plan_.instance[i].name.in ()) != 0) + { + CORBA::ULong cur_len = tmp_plan.instance.length (); + tmp_plan.instance.length (cur_len + 1); + tmp_plan.instance[cur_len] = this->plan_.instance[i]; + } + } + + // package the components + NodeImplementationInfoHandler handler (tmp_plan, + this->shared_components_); + Deployment::NodeImplementationInfo * node_info = + handler.node_impl_info (); + + if (!node_info) + { + this->add_new_components (); + } + + // Install the components + // This is what we will get back, a sequence of compoent object refs. + Deployment::ComponentInfos_var comp_info; + comp_info = this->nodeapp_->install (*node_info); + + // Now fill in the map we have for the components. + const CORBA::ULong comp_len = comp_info->length (); + for (CORBA::ULong len = 0; + len < comp_len; + ++len) + { + //Since we know the type ahead of time...narrow is omitted here. + if (this->component_map_. + bind (comp_info[len].component_instance_name.in(), + Components::CCMObject::_duplicate + (comp_info[len].component_ref.in()))) + { + ACE_CString error ("Duplicate component instance name "); + error += comp_info[len].component_instance_name.in(); + + throw + (Deployment::PlanError + ("NodeApplicationManager_Impl::startLaunch", + error.c_str ())); + } + } + + // NOTE: We are propogating back "all" the facets/consumers object + // references to the DAM, including the previous existing ones. + providedReference = + this->create_connections (); + + if (providedReference == 0) + { + throw + (Deployment::InstallationFailure + ("NodeApplicationManager_Impl::startLaunch", + "Error creating connections during startLaunch.")); + } + } + else // This is a new NodeApplication process, then we need to install + // all the components. We should try to reuse much of the above code. + { + this->startLaunch (configProperty, + providedReference, + start); + } + } + catch (const Deployment::UnknownImplId& e) + { + ACE_THROW_RETURN (Deployment::UnknownImplId (e.name.in (), + e.reason.in ()), + Deployment::Application::_nil()); + } + catch (const Deployment::ImplEntryPointNotFound& e) + { + ACE_THROW_RETURN (Deployment::ImplEntryPointNotFound (e.name.in (), + e.reason.in ()), + Deployment::Application::_nil()); + } + catch (const Deployment::InstallationFailure& e) + { + ACE_THROW_RETURN (Deployment::InstallationFailure (e.name.in (), + e.reason.in ()), + Deployment::Application::_nil()); + } + + return Deployment::NodeApplication::_duplicate (this->nodeapp_.in ()); +} + + +void +CIAO::NodeApplicationManager_Impl_Base:: +add_new_components () + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::PlanError, + ::Deployment::InstallationFailure, + ::Deployment::UnknownImplId, + ::Deployment::ImplEntryPointNotFound, + ::Deployment::InvalidConnection, + ::Deployment::InvalidProperty)) +{ + try + { + // We ignored those components that are already in the <component_map_>, for + // the rest ones, we pack them into NodeImplementationInfo. + Deployment::DeploymentPlan tmp_plan = this->plan_; + tmp_plan.instance.length (0); + + const CORBA::ULong length = this->plan_.instance.length (); + for (CORBA::ULong i = 0; i < length; ++i) + { + // add the new components into the tmp_plan + if (this->component_map_.find (this->plan_.instance[i].name.in ()) != 0) + { + CORBA::ULong cur_len = tmp_plan.instance.length (); + tmp_plan.instance.length (cur_len + 1); + tmp_plan.instance[cur_len] = this->plan_.instance[i]; + } + } + + // If there are no new components to be installed ... + if (tmp_plan.instance.length () == 0) + return; + + // package the components + NodeImplementationInfoHandler handler (tmp_plan, + this->shared_components_); + Deployment::NodeImplementationInfo * node_info = + handler.node_impl_info (); + + if (!node_info) + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) NodeApplicationManager.cpp -" + "CIAO::NodeApplicationManager_Impl::perform_redeployment -" + "Failed to create Node Implementation Infos!\n")); + + throw + (Deployment::PlanError ("NodeApplicationManager_Imp::perform_redeployment", + "Unable to get node level infos")); + } + + // Install the components + // This is what we will get back, a sequence of component object refs. + Deployment::ComponentInfos_var comp_info; + comp_info = this->nodeapp_->install (*node_info); + + // Now fill in the map we have for the components. + const CORBA::ULong comp_len = comp_info->length (); + for (CORBA::ULong len = 0; + len < comp_len; + ++len) + { + //Since we know the type ahead of time...narrow is omitted here. + if (this->component_map_. + bind (comp_info[len].component_instance_name.in(), + Components::CCMObject::_duplicate + (comp_info[len].component_ref.in()))) + { + ACE_CString error ("Duplicate component instance name "); + error += comp_info[len].component_instance_name.in(); + + throw + (Deployment::PlanError + ("NodeApplicationManager_Impl::startLaunch", + error.c_str ())); + } + } + } + catch (const CORBA::Exception&) + { + ACE_ERROR ((LM_ERROR, "NodeApplicationManager_Impl_Base::" + "add_new_components () exception caught.\n")); + throw; + } +} + + +void +CIAO::NodeApplicationManager_Impl_Base:: +remove_existing_components () + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::PlanError, + ::Components::RemoveFailure)) +{ + try + { + ACE_Vector<ACE_CString> gone_component_list; + + for (Component_Iterator iter (this->component_map_.begin ()); + iter != this->component_map_.end (); + ++iter) + { + ACE_CString comp_name ((*iter).ext_id_.c_str ()); + + // If this component is not in the new deployment plan, then we + // should destroy this component and unbind from the map. + if (this->is_to_be_removed (comp_name.c_str ())) + { + ((*iter).int_id_)->ciao_passivate (); + this->nodeapp_->remove_component (comp_name.c_str ()); + gone_component_list.push_back (comp_name); + } + } + + for (size_t i = 0; i < gone_component_list.size (); ++i) + this->component_map_.unbind (gone_component_list[i]); + } + catch (const CORBA::Exception&) + { + ACE_ERROR ((LM_ERROR, "NodeApplicationManager_Impl_Base::" + "remove_existing_components () exception caught.\n")); + throw; + } +} + +bool +CIAO::NodeApplicationManager_Impl_Base:: +is_to_be_removed (const char * name) +{ + const CORBA::ULong length = this->plan_.instance.length (); + for (CORBA::ULong i = 0; i < length; ++i) + { + if (ACE_OS::strcmp (name, + this->plan_.instance[i].name.in ()) == 0) + { + // If we have found it in the new plan, then this component + // needs to be kept, and should not be removed. + return false; + } + } + return true; +} + +void +CIAO::NodeApplicationManager_Impl_Base:: +set_shared_components (const Deployment::ComponentPlans & shared) + ACE_THROW_SPEC ((::CORBA::SystemException)) +{ + this->shared_components_ = shared; +} + +void +CIAO::NodeApplicationManager_Impl_Base:: +destroyApplication (Deployment::Application_ptr app) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)) +{ + CIAO_TRACE("CIAO::NodeApplicationManager_Impl::destroyApplication"); + ACE_UNUSED_ARG (app); + + ACE_DEBUG ((LM_DEBUG, "NAM: entering DA\n")); + //ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_); + //@@ Since we know there is only 1 nodeapp so the passed in + // parameter is ignored for now. + if (CORBA::is_nil (this->nodeapp_.in () )) + throw Deployment::StopError (); + + // Iterate over all the components within this NAM, and if it's + // not a shared component, then remove it. If all the components + // are removed, then we shall kill the NA totally. + for (CORBA::ULong i = 0; i < this->plan_.instance.length (); ++i) + { + ACE_DEBUG ((LM_DEBUG, "NAM: first for loop: %s\n", + this->plan_.instance[i].name.in ())); + ACE_CString name = plan_.instance[i].name.in (); + if (this->is_shared_component (name)) + { + this->component_map_.unbind (name); + continue; + } + + // If this is not a shared component and is installed within + // this NAM, then remove it. Otherwise, we do nothing. + // Ideally, we should ask NM to remove this component for + // us even if this is not within this NAM. + if (! this->is_external_component (name)) + { + this->nodeapp_->remove_component (name.c_str ()); + this->component_map_.unbind (name); + } + } + + // Call remove on NodeApplication, if all the components are removed, + // then the NodeApplication will kill itself. + ACE_DEBUG ((LM_DEBUG, "NAM: calling remove\n")); + this->nodeapp_->remove (); + ACE_DEBUG ((LM_DEBUG, "NAM: remove returned\n")); + + return; +} + +// The set priority method +::CORBA::Long +CIAO::NodeApplicationManager_Impl_Base::set_priority ( + const char * cid, + const ::Deployment::Sched_Params & params) + ACE_THROW_SPEC ((::CORBA::SystemException)) +{ + if (CIAO::debug_level () > 20) + { + ACE_DEBUG ((LM_DEBUG , "NAM::The component Id received [%s]", cid)); + + ACE_DEBUG ((LM_DEBUG , + "NAM::The params are policy [%d], priority [%d], " + "scope [%d], time [%d]\n", + params.policy_ , + params.priority_, + params.scope_, params.msec_)); + } + + // First validate the values coming in .... + ACE_Sched_Params::Policy policy = params.policy_; + + if (policy != ACE_SCHED_FIFO && + policy != ACE_SCHED_RR && + policy != ACE_SCHED_OTHER) + return -1; + + ACE_Sched_Priority priority = params.priority_; + + // check the scope .. + if (params.scope_ != ACE_SCOPE_PROCESS && + params.scope_ != ACE_SCOPE_THREAD && + params.scope_ != ACE_SCOPE_LWP) + { + return -1; + } + + // Here form the ACE_Sched_Params structure and pass it on to the Process + // manager with the current process id. + // @@ TODO: Right now we are ignoring params.msec_ value since + // ACE_OS::sched_params fails setting errno = EINVAL if + // scope = ACE_PROCESS_SCOPE and quantun != ACE_Time_Value:zero. + ACE_Sched_Params sched_params (policy , + priority, + params.scope_, + ACE_Time_Value::zero); + + // Enable FIFO scheduling, e.g., RT scheduling class on Solaris. + if (node_app_process_manager_.set_scheduler (sched_params, process_id_) != 0) + { + if (ACE_OS::last_error () == EPERM) + { + ACE_DEBUG ((LM_DEBUG, + "User is not superuser, therefore cannot modify the " + "priority of the component\n")); + } + else if (ACE_OS::last_error () == ESRCH) + { + ACE_DEBUG ((LM_DEBUG, + "No process with PID: %d was found!\n", + process_id_)); + } + else if (ACE_OS::last_error () == EINVAL) + { + ACE_DEBUG ((LM_DEBUG, "\nGiven sched_params does not make sence " + "for the current scheduling policy\n")); + } + ACE_ERROR ((LM_ERROR, "NodeApplicationManager (%P|%t): sched_params " + "failed\n")); + return -1; + } + return 1; +} + + +CIAO::NodeApplicationManager_Impl::~NodeApplicationManager_Impl (void) +{ +} + +CIAO::NodeApplicationManager_Impl:: +NodeApplicationManager_Impl (CORBA::ORB_ptr o, + PortableServer::POA_ptr p) + : NodeApplicationManager_Impl_Base (o, p) +{ +} + +PortableServer::ObjectId +CIAO::NodeApplicationManager_Impl::init ( + const char *nodeapp_location, + const char *nodeapp_op, + const CORBA::ULong delay, + const Deployment::DeploymentPlan & plan, + const PortableServer::POA_ptr callback_poa, + NodeManager_Impl_Base * nm) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidProperty)) +{ + PortableServer::ObjectId_var oid; + + try + { + if (nodeapp_location == 0) + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) NodeApplicationManager_Impl.cpp -" + "CIAO::NodeApplicationManager_Impl::init -" + "NULL NodeApplication location. \n")); + throw CORBA::BAD_PARAM (); + } + + if (delay == 0) + { + ACE_ERROR ((LM_ERROR, + "DAnCE (%P|%t) NodeApplicationManager_Impl.cpp -" + "CIAO::NodeApplicationManager_Impl::init -" + "NodeManager must be started with a -d " + "of greter than zero.\n")); + throw CORBA::BAD_PARAM (); + } + + this->nodeapp_path_.set (nodeapp_location); + this->spawn_delay_ = delay; + this->nodeapp_command_op_ = CORBA::string_dup (nodeapp_op); + this->node_manager_ = nm; + + // Make a copy of the plan for later usage. + this->plan_ = plan; + + // Cache the call back POA for callback object. + this->callback_poa_ = PortableServer::POA::_duplicate (callback_poa); + + // Activate the ourself. + oid = this->poa_->activate_object (this); + + CORBA::Object_var obj = + this->poa_->id_to_reference (oid.in ()); + + // And cache the object reference. + this->objref_ = + Deployment::NodeApplicationManager::_narrow (obj.in ()); + + // add the signal handler to the ACE_REACTOR + + /* + if (orb_->orb_core ()->reactor ()-> + register_handler (SIGCHLD, + &child_handler_) == -1) + + if (ACE_Reactor::instance ()->register_handler (SIGCHLD, + &child_handler_) == -1) + { + ACE_DEBUG ((LM_DEBUG, "Error in registering Handler\n\n")); + } + */ + } + + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("NodeApplicationManager_Impl_Base::init\t\n"); + throw; + } + + //return this object reference + return oid.in (); +} + +Deployment::NodeApplication_ptr +CIAO::NodeApplicationManager_Impl:: +create_node_application (const ACE_CString & options) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty)) +{ + CIAO_TRACE("CIAO::NodeApplicationManager_Impl::create_node_application"); + Deployment::NodeApplication_var retval; + Deployment::Properties_var prop; + + ACE_NEW_THROW_EX (prop, + Deployment::Properties, + CORBA::NO_MEMORY ()); + + // @@ Create a new callback servant. + CIAO::NodeApplication_Callback_Impl * callback_servant = 0; + ACE_NEW_THROW_EX (callback_servant, + CIAO::NodeApplication_Callback_Impl (this->orb_.in (), + this->callback_poa_.in (), + this->objref_.in (), + prop.in ()), + CORBA::NO_MEMORY ()); + + PortableServer::ServantBase_var servant_var (callback_servant); + PortableServer::ObjectId_var cb_id + = this->callback_poa_->activate_object (callback_servant); + + ACE_Process_Options p_options; + ACE_Process_Manager process_manager; + + process_manager.open (10, ACE_Reactor::instance ()); + + try + { + CORBA::Object_var cb_obj = + this->callback_poa_->id_to_reference (cb_id.in ()); + + CIAO::NodeApplication_Callback_var cb = + CIAO::NodeApplication_Callback::_narrow (cb_obj.in ()); + + CORBA::String_var cb_ior = + this->orb_->object_to_string (cb.in ()); + + // spawn the new NodeApplication. + p_options.command_line ("%s -k %s " + "%s", + this->nodeapp_path_.c_str (), + cb_ior.in (), + options.c_str ()); + + p_options.avoid_zombies (0); + + process_id_ = node_app_process_manager_.spawn (p_options, + &child_handler_); + + if (process_id_ == ACE_INVALID_PID) + { + if (CIAO::debug_level () > 1) + { + ACE_ERROR ((LM_ERROR, + "Fail to spawn a NodeApplication process\n")); + } + + throw + (Deployment::ResourceNotAvailable + ("Failed to spawn process", + "NodeApplication", + "", + "", + "")); + } + + // wait for nodeApp to pass back its object reference. with a + // timeout value. using perform_work and stuff. + bool looping = true; + + ACE_Time_Value timeout (this->spawn_delay_, 0); + + while (looping) + { + this->orb_->perform_work (timeout); + + retval = callback_servant->get_nodeapp_ref (); + + if (timeout == ACE_Time_Value::zero || !CORBA::is_nil (retval.in ())) + looping = false; + } + + if (CORBA::is_nil (retval.in ())) + { + if (CIAO::debug_level () > 1) + { + ACE_ERROR ((LM_ERROR, + "Fail to acquire the NodeApplication object\n")); + } + + throw Deployment::ResourceNotAvailable (); + } + + { + //ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); + this->nodeapp_ = + Deployment::NodeApplication::_duplicate (retval.in ()); + } + } + catch (const CORBA::Exception&) + { + this->callback_poa_->deactivate_object (cb_id.in ()); + + throw; + } + + this->callback_poa_->deactivate_object (cb_id.in ()); + + if (CIAO::debug_level () > 1) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO::NodeApplicationManager_Impl::NodeApplication spawned!\n")); + } + + // push the component info and the process id to the + // NodeManager + push_component_info (process_id_); + + + return retval._retn (); +} + + +void +CIAO::NodeApplicationManager_Impl:: +push_component_info (pid_t process_id) +{ + CIAO::NodeManager_Impl_Base::Component_Ids comp; + + for (unsigned int i=0;i < plan_.instance.length ();i++) + { + if (CIAO::debug_level () > 10) + { + ACE_DEBUG ((LM_DEBUG, "The component id is [%s]", + plan_.instance[i].name.in ())); + } + comp.cid_seq_.insert (plan_.instance[i].name.in ()); + } + + comp.process_id_ = process_id; + + node_manager_->push_component_id_info (comp); +} + + +CIAO::Static_NodeApplicationManager_Impl::~Static_NodeApplicationManager_Impl (void) +{ +} + +CIAO::Static_NodeApplicationManager_Impl:: +Static_NodeApplicationManager_Impl (CORBA::ORB_ptr o, + PortableServer::POA_ptr p, + Static_Config_EntryPoints_Maps* static_config_entrypoints_maps) + : NodeApplicationManager_Impl_Base (o, p), + static_config_entrypoints_maps_ (static_config_entrypoints_maps) +{ +} + +PortableServer::ObjectId +CIAO::Static_NodeApplicationManager_Impl::init ( + const char *nodeapp_location, + const char *nodeapp_op, + const CORBA::ULong delay, + const Deployment::DeploymentPlan & plan, + const PortableServer::POA_ptr callback_poa, + NodeManager_Impl_Base * nm) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidProperty)) +{ + PortableServer::ObjectId_var oid; + + ACE_UNUSED_ARG (nodeapp_location); + ACE_UNUSED_ARG (nodeapp_op); + ACE_UNUSED_ARG (delay); + ACE_UNUSED_ARG (callback_poa); + + try + { + this->node_manager_ = nm; + + // Make a copy of the plan for later usage. + this->plan_ = plan; + + // Activate the ourself. + oid = this->poa_->activate_object (this); + + CORBA::Object_var obj = + this->poa_->id_to_reference (oid.in ()); + + // And cache the object reference. + this->objref_ = + Deployment::NodeApplicationManager::_narrow (obj.in ()); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("NodeApplicationManager_Impl_Base::init\t\n"); + throw; + } + + //return this object reference + return oid.in (); +} + +Deployment::NodeApplication_ptr +CIAO::Static_NodeApplicationManager_Impl:: +create_node_application (const ACE_CString & options) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty)) +{ + ACE_UNUSED_ARG(options); + + CIAO::NodeApplication_Impl *nodeapp_servant; + + ACE_DEBUG ((LM_DEBUG, "create_static_node_application\n")); + + ACE_NEW_RETURN (nodeapp_servant, + CIAO::NodeApplication_Impl (orb_.in (), + poa_.in (), + configurator_, + this->static_config_entrypoints_maps_), + Deployment::NodeApplication::_nil () + ); + if (nodeapp_servant->init ()) + { + ACE_DEBUG ((LM_DEBUG, "NodeApplication Failed on creating and\ + initializing the session container!")); + return Deployment::NodeApplication::_nil (); + } + + // CONFIGURING NodeApplication + PortableServer::ObjectId_var nodeapp_oid + = poa_->activate_object (nodeapp_servant); + + CORBA::Object_var + obj = poa_->id_to_reference (nodeapp_oid.in ()); + + Deployment::NodeApplication_var nodeapp_obj = + Deployment::NodeApplication::_narrow (obj.in ()); + + if (CORBA::is_nil (nodeapp_obj.in ())) + { + ACE_ERROR ((LM_ERROR, "Unable to activate NodeApplication object\n")); + return Deployment::NodeApplication::_nil (); + } + + this->nodeapp_ = Deployment::NodeApplication::_duplicate (nodeapp_obj.in ()); + + return nodeapp_obj._retn (); +} + +CIAO::NodeApplicationManager_Impl_Base::~NodeApplicationManager_Impl_Base (void) +{ +} + diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.h b/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.h new file mode 100644 index 00000000000..5ea55596f1b --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.h @@ -0,0 +1,404 @@ +// $Id$ + +// -*- C++ -*- + +//============================================================================= +/** + * @file NodeApplicationManager_Impl.h + * + * @author Tao Lu <lu@dre.vanderbilt.edu> + * @author Gan Deng <dengg@dre.vanderbilt.edu> + * + * This file contains implementation for the servant of + * Deployment::NodeApplicationManager. + */ +//============================================================================= + + +#ifndef CIAO_NODEAPPLICATIONMANAGER_IMPL_H +#define CIAO_NODEAPPLICATIONMANAGER_IMPL_H +#include /**/ "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SString.h" +#include "ace/Hash_Map_Manager_T.h" +#include "ace/OS_NS_sys_wait.h" +#include "ace/Process_Manager.h" +#include "ciao/NodeApp_CB_Impl.h" +#include "ciao/Deployment_NodeApplicationManagerS.h" +#include "ciao/CIAO_common.h" +#include "CIAO_NAM_Export.h" +#include "ImplementationInfo.h" +#include "NodeManager/NodeManager_Impl.h" +#include "NodeApplication/NodeApplication_Core.h" + +namespace CIAO +{ + + /** + * @class NodeApplicationManager_Impl_Base + */ + class CIAO_NAM_Export NodeApplicationManager_Impl_Base + : public virtual POA_Deployment::NodeApplicationManager + { + public: + /// Constructor + NodeApplicationManager_Impl_Base (CORBA::ORB_ptr o, + PortableServer::POA_ptr p); + + /*=========================================================== + * Below are operations from the NodeApplicationManager + * + *============================================================*/ + + /// The return type is NodeApplication_ptr actually. + /// For "external/shared" components of this child plan, they are + /// not actaully installed, however, the object references + /// of the ports of these external components are returned + /// through <providedReference>. + virtual Deployment::Application_ptr + startLaunch (const Deployment::Properties & configProperty, + Deployment::Connections_out providedReference, + CORBA::Boolean start) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty)); + + //@@ Destroy the whole applicaton. + virtual void destroyApplication (Deployment::Application_ptr) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError)); + + virtual Deployment::Application_ptr + perform_redeployment (const Deployment::Properties & configProperty, + Deployment::Connections_out providedReference, + CORBA::Boolean add_or_remove, + CORBA::Boolean start) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::PlanError, + ::Deployment::InstallationFailure, + ::Deployment::UnknownImplId, + ::Deployment::ImplEntryPointNotFound, + ::Deployment::InvalidConnection, + ::Deployment::InvalidProperty, + ::Components::RemoveFailure)); + + virtual void + reset_plan (const ::Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC ((::CORBA::SystemException)); + + virtual void + set_shared_components (const Deployment::ComponentPlans & shared) + ACE_THROW_SPEC ((::CORBA::SystemException)); + + /** + * A factory operation to create NodeApplicationManager interface, and return + * the object reference. + * Initialize the NodeApplicationManager. The current implementation + * of CIAO_NodeApplicationManager can only activate CIAO's own + * NodeApplication processes. You should specify the location + * (pathname) of the NodeApplication and the delay. + * CIAO_NodeApplicationManager should wait (in second) for NodeApplication to + * call back. + * + * @param nodeapp_location A null-termiated char * string pointing + * to the pathname of a NodeApplication executable. + * + * @param nodeapp_options A null-terminated char * string + * containing command line options to be passed to the + * NodeApplication. + * + * @param delay instructs how long (in second) a CIAO_NodeApplicationManager + * should wait for a newly spawned NodeApplication to pass back + * its IOR. + * + * @param plan has all the information needed for the NodeAppManager to + * construct the application locally. Note, this includes the properties + * of the NodeApplication. For example, ORB config options etc. + * + * @param callback_poa contains child poa created for the callback interface. + * + * @para nm Pointer to the NodeManager_Impl servant object + * + * @return NodeApplicationManager_ptr. + **/ + virtual PortableServer::ObjectId + init (const char *nodeapp_location, + const char *nodeapp_options, + const CORBA::ULong delay, + const Deployment::DeploymentPlan & plan, + const PortableServer::POA_ptr callback_poa, + NodeManager_Impl_Base * nm) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidProperty))=0; + + /// @note This method doesn't do duplicate. + Deployment::NodeApplicationManager_ptr get_nodeapp_manager (void); + + /// Set the priority of the NodeApplication process which this NAM manages + virtual ::CORBA::Long set_priority ( + const char * cid, + const ::Deployment::Sched_Params & params) + ACE_THROW_SPEC ((CORBA::SystemException )); + + protected: + /// Destructor + virtual ~NodeApplicationManager_Impl_Base (void); + + /// Add new components + virtual void + add_new_components (void) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::PlanError, + ::Deployment::InstallationFailure, + ::Deployment::UnknownImplId, + ::Deployment::ImplEntryPointNotFound, + ::Deployment::InvalidConnection, + ::Deployment::InvalidProperty)); + + /// Remove existing components + virtual void + remove_existing_components (void) + ACE_THROW_SPEC ((CORBA::SystemException, + ::Deployment::PlanError, + ::Components::RemoveFailure)); + + /// Determine whether a component is absent in the new_plan + /// Return true if absent + virtual bool + is_to_be_removed (const char * name); + + /// Internal help function to create new NodeApplicationProcess + virtual Deployment::NodeApplication_ptr + create_node_application (const ACE_CString & options) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty))=0; + + /// Helper function to get the connection. + virtual Deployment::Connections * + create_connections () + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty)); + + /** + * Find the configurations in the plan and prepare them to pass to the + * NodeApplication, from command line probably. + */ + void parse_config_value (ACE_CString & str) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidProperty)); + + /// Helper function to check wheather a component instance + /// is in the "shared components list". + bool is_shared_component (ACE_CString & name); + + /// Helper function to check wheather a component instance + /// is in the "shared components list". + bool is_external_component (ACE_CString & name); + + protected: + /// location of the Nodeapplication + ACE_CString nodeapp_path_; + + /// Keep a pointer to the managing ORB serving this servant. + CORBA::ORB_var orb_; + + /// Keep a pointer to the managing POA. + PortableServer::POA_var poa_; + + /// Pointer to the NodeManager_Impl servant object + /// We could do this because NodeManager and NodeApplicationManager + /// are always collocated in the same process, so we don't have + /// to pass CORBA object reference back and forth. + NodeManager_Impl_Base * node_manager_; + + /// ObjectRef of ourself which will be needed by the callback + Deployment::NodeApplicationManager_var objref_; + + /// Child poa that uses active object map. + PortableServer::POA_var callback_poa_; + + /// Cache a object reference of the underlying NodeApplication + /// Since I have decided to have only 1 NA in NAM so no map is needed. + Deployment::NodeApplication_var nodeapp_; + + /// Cached plan (This should be the part of the whole plan local to this node) + /// The plan will be initialized when init is called. + Deployment::DeploymentPlan plan_; + + /// Specify the time in second NodeApplicationManager will wait for a + /// child NodeApplication to callback. Default is 5 second. + CORBA::ULong spawn_delay_; + + /// Extracted commandline options to pass to the NodeApplication. + CORBA::String_var nodeapp_command_op_; + + /// A list of components shared across deployment plans + Deployment::ComponentPlans shared_components_; + + /// A list of components that are "external" to this plan + Deployment::ComponentPlans external_components_; + + /// A map of the component created on this node. + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + Components::CCMObject_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> CCMComponent_Map; + typedef CCMComponent_Map::iterator Component_Iterator; + CCMComponent_Map component_map_; + + /// Synchronize access to the object set. + TAO_SYNCH_MUTEX lock_; + + /// The Process Manager for this NodeApplicationManager + ACE_Process_Manager node_app_process_manager_; + + /// The process id of the NA associated with the NAM, + /// Each NAM will only have one NA associated with it, + /// so we have only one process associated with it. + + // this is UNIX specific .... not portable + pid_t process_id_; + }; + + + /** + * @class NAM_Handler + * @brief The signal handler class for the SIGCHLD + * handling to avoid zombies + * + */ + class NAM_Handler : public ACE_Event_Handler + { + public: + virtual int handle_signal (int sig, + siginfo_t *, + ucontext_t *) + { + ACE_UNUSED_ARG (sig); + + // @@ Note that this code is not portable to all OS platforms + // since it uses print statements within signal handler context. + //ACE_DEBUG ((LM_DEBUG, + // "Executed ACE signal handler for signal %S \n", + // sig)); + + ACE_exitcode status; + // makes a claal to the underlying os system call + // -1 to wait for any child process + // and WNOHANG so that it retuurns immediately + ACE_OS::waitpid (-1 ,&status, WNOHANG, 0); + + return 0; + } + }; + + + /** + * @class NodeApplicationManager_Impl + */ + class CIAO_NAM_Export NodeApplicationManager_Impl + : public virtual NodeApplicationManager_Impl_Base + { + public: + /// Constructor + NodeApplicationManager_Impl (CORBA::ORB_ptr o, + PortableServer::POA_ptr p); + + virtual PortableServer::ObjectId + init (const char *nodeapp_location, + const char *nodeapp_options, + const CORBA::ULong delay, + const Deployment::DeploymentPlan & plan, + const PortableServer::POA_ptr callback_poa, + NodeManager_Impl_Base * nm) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidProperty)); + + protected: + /// Destructor + virtual ~NodeApplicationManager_Impl (void); + + // Internal help function to create new NodeApplicationProcess + // Here we override it to create an in-process NodeApplication object + virtual Deployment::NodeApplication_ptr + create_node_application (const ACE_CString & options) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty)); + + + /** + * @operation push_component_info + * @brief pushes component info to the NodeManager + * + * @param process_id The id of the process of NodeApplication + */ + void push_component_info (pid_t process_id); + + /// The signal handler + NAM_Handler child_handler_; + }; + + + struct Static_Config_EntryPoints_Maps; + + /** + * @class Static_NodeApplicationManager_Impl + */ + class CIAO_NAM_Export Static_NodeApplicationManager_Impl + : public virtual NodeApplicationManager_Impl_Base + { + public: + /// Constructor + Static_NodeApplicationManager_Impl (CORBA::ORB_ptr o, + PortableServer::POA_ptr p, + Static_Config_EntryPoints_Maps* static_config_entrypoints_maps); + + virtual PortableServer::ObjectId + init (const char *nodeapp_location, + const char *nodeapp_options, + const CORBA::ULong delay, + const Deployment::DeploymentPlan & plan, + const PortableServer::POA_ptr callback_poa, + NodeManager_Impl_Base * nm) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidProperty)); + + protected: + /// Destructor + virtual ~Static_NodeApplicationManager_Impl (void); + + /// Internal help function to create new NodeApplicationProcess + /// Here we override it to create an in-process NodeApplication object + virtual Deployment::NodeApplication_ptr + create_node_application (const ACE_CString & options) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::ResourceNotAvailable, + Deployment::StartError, + Deployment::InvalidProperty)); + + Static_Config_EntryPoints_Maps* static_config_entrypoints_maps_; + + CIAO::NoOp_Configurator configurator_; + }; +} + +#if defined (__ACE_INLINE__) +# include "NodeApplicationManager_Impl.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* CIAO_NODEAPPLICATIONMANAGER_IMPL_H */ diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.inl b/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.inl new file mode 100644 index 00000000000..49bdc80098e --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.inl @@ -0,0 +1,49 @@ +/* -*- C++ -*- */ +// $Id$ + +ACE_INLINE +CIAO::NodeApplicationManager_Impl_Base:: +NodeApplicationManager_Impl_Base (CORBA::ORB_ptr o, + PortableServer::POA_ptr p) + : orb_ (CORBA::ORB::_duplicate (o)), + poa_ (PortableServer::POA::_duplicate (p)), + callback_poa_ (PortableServer::POA::_nil ()), + nodeapp_ (Deployment::NodeApplication::_nil ()), + spawn_delay_ (5) + // @@ (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 component_map_ is + // appropriate for your needs. You may also want to make + // the size configurable at compile-time, at least. +{ +} + +ACE_INLINE +void +CIAO::NodeApplicationManager_Impl_Base:: +parse_config_value (ACE_CString & str) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::InvalidProperty)) +{ + // The unused arg is for future improvemnts. + ACE_UNUSED_ARG (str); + + throw CORBA::NO_IMPLEMENT(); +} + +ACE_INLINE +Deployment::NodeApplicationManager_ptr +CIAO::NodeApplicationManager_Impl_Base::get_nodeapp_manager (void) +{ + return this->objref_.in (); +} + +ACE_INLINE void +CIAO::NodeApplicationManager_Impl_Base:: +reset_plan (const ::Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC ((::CORBA::SystemException)) +{ + this->plan_ = plan; +} + diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/URL_Parser.cpp b/modules/CIAO/DAnCE/NodeApplicationManager/URL_Parser.cpp new file mode 100644 index 00000000000..5d211603614 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/URL_Parser.cpp @@ -0,0 +1,115 @@ +// $Id$ + +#include "URL_Parser.h" + +#include "ace/ACE.h" +#include "ace/OS_NS_string.h" + +bool +URL_Parser::parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("rwu:h:p:f:d")); + + bool success = true; + int c; + + while ((c = get_opt ()) != -1) + { + switch (c) + { + case 'd': + this->debug_ = 1; + break; + case 'u': + success = parseURL (get_opt.opt_arg ()); + break; + // Usage fallthrough. + default: + success = false; + break; + } + } + + if (this->hostname_ == 0 || this->filename_ == 0) + { + success = false; + } + + return success; +} + +URL_Parser::URL_Parser (void) + : hostname_ (ACE::strnew ("127.0.0.1")), + port_ (ACE_DEFAULT_HTTP_SERVER_PORT), + filename_ (0), + debug_ (0) +{ +} + +bool URL_Parser::parseURL (char* url) +{ + char* ptr = ACE_OS::strstr (url, "http://"); + bool success = true; + + if (0 != ptr) + { + url += ACE_OS::strlen ("http://"); + } + + if (url[0] == '/') + { + this->filename_ = ACE_OS::strdup (url); + } + else + { + ptr = ACE_OS::strstr (url, ":"); + + if (0 != ptr) + { + this->port_ = ACE_OS::atoi (ptr + 1); + } + else + { + ptr = ACE_OS::strstr (url, "/"); + } + + if (0 == ptr) + { + success = false; + } + else + { + size_t host_len = ptr - url; + ACE::strdelete (this->hostname_); + ACE_NEW_RETURN (this->hostname_, char [host_len + 1], false); + ACE_OS::strncpy (this->hostname_, url, host_len); + this->hostname_ [host_len] = '\0'; + ptr = ACE_OS::strstr (ptr, "/"); + + if (0 != ptr) + { + this->filename_ = ACE_OS::strdup (ptr); + } + else + { + success = false; + } + } + } + + return success; +} + + +void URL_Parser::Error (void) +{ + ACE_DEBUG ((LM_DEBUG, + "./http_client -u http://hostname:port/filename [-d]\n")); +} + + +URL_Parser::~URL_Parser (void) +{ + delete [] this->hostname_; + ACE_OS::free (this->filename_); +} diff --git a/modules/CIAO/DAnCE/NodeApplicationManager/URL_Parser.h b/modules/CIAO/DAnCE/NodeApplicationManager/URL_Parser.h new file mode 100644 index 00000000000..0aec98cec65 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeApplicationManager/URL_Parser.h @@ -0,0 +1,67 @@ + +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file URL_Parser.h + * + * $Id$ + * + * Parses a URL into its logical chunks + * + * @author Stoyan Paunov + */ +//============================================================================= + + +#ifndef URL_PARSER_H +#define URL_PARSER_H + +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "ace/Singleton.h" //for ACE_Singleton +#include "ace/Null_Mutex.h" //for ACE_Null_Mutex + +//forward declaration +class URL_Parser; + +typedef ACE_Singleton <URL_Parser, ACE_Null_Mutex> TheURL_Parser; + + +class URL_Parser +{ +public: + + friend class ACE_Singleton <URL_Parser, ACE_Null_Mutex>; + + /// Parses commandline arguments + bool parse_args (int argc, ACE_TCHAR *argv[]); + + // Return false on failure + bool parseURL (char* url); + + void Error (void); + + /// Hostname to connect to + ACE_TCHAR *hostname_; + + /// Port number to use + u_short port_; + + /// Filename to upload/download + ACE_TCHAR *filename_; + + /// turns on verbosity + int debug_; + + /// Destructor + ~URL_Parser (void); + +protected: + /// protected constructor, singleton + URL_Parser (void); +}; + + + +#endif /* URL_PARSER_H */ diff --git a/modules/CIAO/DAnCE/NodeManager/BaseMonitor.h b/modules/CIAO/DAnCE/NodeManager/BaseMonitor.h new file mode 100644 index 00000000000..d05e798b523 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/BaseMonitor.h @@ -0,0 +1,63 @@ +// $Id$ +//---------------------------------------------------------------------------------- +/// Monitor Interface +/* + * @file BaseMonitor.h + * @brief The BaseMonitor.h file. + * This is an abstract class containing the interface to the Monitor plug-in + * + * @author Nilabja R <nilabjar@dre.vanderbilt.edu> + */ +//---------------------------------------------------------------------------------- + +#ifndef MONITOR_BASEH +#define MONITOR_BASEH +#include "tao/ORB.h" +#include "ciao/Deployment_TargetManagerC.h" + +namespace CIAO +{ + + class MonitorBase + { + public: + virtual ~MonitorBase () {}; + + /** + * This function is called by the controller to initialize + * parameters. + * @param domain The Initital domain for this host + * @param target_manager TargetManager_ptr + * @param interval The time interval after which updates need to be send. + */ + virtual int initialize_params ( + ::Deployment::Domain& domain, + ::Deployment::TargetManager_ptr target_manager, + int interval + )=0; + /** + * This function is called by the controller + * to start up the monitor. + * @param orb The ORB pointer + */ + virtual int start (CORBA::ORB_ptr orb) = 0; + /** + * This function is called by the controller + * to stop the monitor. + */ + virtual int stop ()=0; + /** + * This function is called by the controller + * to get the current data. + * @return The current Domain data + */ + virtual ::Deployment::Domain* get_current_data ()=0; + }; + + extern "C" ACE_Proper_Export_Flag CIAO::MonitorBase * + createMonitor (void); + +} // CIAO + + +#endif /* MONITOR_BASEH */ diff --git a/modules/CIAO/DAnCE/NodeManager/CIAO_Monitor.cpp b/modules/CIAO/DAnCE/NodeManager/CIAO_Monitor.cpp new file mode 100644 index 00000000000..9d9417da520 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/CIAO_Monitor.cpp @@ -0,0 +1,155 @@ +// $Id$ +//========================================================================== +/// The RSS Monitor class defination +/** + * @file CIAO_Monitor.cpp + * + * @brief The Monitor class defination + * + * @author Nilabja Roy <nilabjar@dre.vanderbilt.edu> + */ +//========================================================================== + +#include "CIAO_Monitor.h" +#include "CIAO_common.h" +#include "ace/OS_NS_stdio.h" + +extern "C" ACE_Proper_Export_Flag CIAO::MonitorBase * CIAO::createMonitor () +{ + CIAO::CIAO_Monitor* monitor = 0; + ACE_NEW_RETURN (monitor, CIAO::CIAO_Monitor, 0); + return monitor; +} + +CIAO::CIAO_Monitor::CIAO_Monitor () +{ +} + +/// The Desctructor +CIAO::CIAO_Monitor::~CIAO_Monitor () +{ +} + +int CIAO::CIAO_Monitor::initialize_params ( + ::Deployment::Domain& domain, + ::Deployment::TargetManager_ptr target_manager, + int interval + ) +{ + current_domain_.reset (new ::Deployment::Domain (domain)); + target_ptr_= target_manager; + this->interval_=interval; + + return 0; +} + +int CIAO::CIAO_Monitor::start (CORBA::ORB_ptr) +{ + return 0; +} + +int CIAO::CIAO_Monitor::stop () +{ + return 0; +} + +::Deployment::Domain* CIAO::CIAO_Monitor::get_current_data () +{ + if (CIAO::debug_level () > 9) + { + // ACE_DEBUG ((LM_DEBUG , + // "CIAO_Monitor::Inside the get_current_data of[%s]\n", + // current_domain_->node[0].name.in ())); + } + + CORBA::Double current_load = 0; + + long user_cpu; + long user_cpu_low; + long sys_cpu; + long idle_time; + + // get the load average value from the /proc/loadavg + + FILE *load_file = 0; + + load_file = ACE_OS::fopen ("/proc/stat", "r"); + + if (load_file == 0) + { + // load file cannot be opened .. + current_load = 0; + } + else + { + char buffer [99]; + + // read in the cpu label + fscanf (load_file, "%s", buffer); + + //read the user_cpu + fscanf (load_file, "%ld", &user_cpu); + + //read the user cpu low priority + fscanf (load_file, "%ld", &user_cpu_low); + + //read the system cpu + fscanf (load_file, "%ld", &sys_cpu); + + //read the cpu in idle time .. + fscanf (load_file, "%ld", &idle_time); + + ACE_OS::fclose (load_file); + + // Calculate the percent CPU + long const current_user_cpu = user_cpu - prev_user_cpu_; + long const total_cpu_usage = user_cpu + user_cpu_low + sys_cpu + + idle_time - prev_user_cpu_ - prev_idle_time_ - prev_sys_cpu_ + - prev_user_cpu_low_; + + current_load = (current_user_cpu * 100)/total_cpu_usage; + + // Save the current cpu values in the previous variables + + prev_user_cpu_ = user_cpu; + + prev_user_cpu_low_ = user_cpu_low; + + prev_sys_cpu_ = sys_cpu; + + prev_idle_time_ = idle_time; + + } + + + CORBA::Any any; + any <<= current_load; + + // here insert the util value, in the right position + + for (unsigned int i = 0; + i < current_domain_->node[0].resource.length (); + i++) + { + if (!ACE_OS::strcmp (current_domain_->node[0].resource[i].name, "Processor")) + { + for (unsigned int j = 0; + j < current_domain_->node[0].resource[i].property.length (); + j++) + { + if (!ACE_OS::strcmp ( + current_domain_ + ->node[0].resource[i].property[j].name.in (), + "LoadAverage")) + { + current_domain_->node[0].resource[i].property[j].kind = + ::Deployment::Quantity; + current_domain_->node[0].resource[i].property[j].value = + any; + } + } + } + } + + return current_domain_.get (); +} diff --git a/modules/CIAO/DAnCE/NodeManager/CIAO_Monitor.h b/modules/CIAO/DAnCE/NodeManager/CIAO_Monitor.h new file mode 100644 index 00000000000..5a134538701 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/CIAO_Monitor.h @@ -0,0 +1,107 @@ +// $Id$ +//========================================================================== +/** + * @file CIAO_Monitor.h + * + * @brief The Monitor class. + * + * This class periodically records the loadavg value of the machine in which it + * loaded + * + * @author Nilabja Roy <nilabjar@dre.vanderbilt.edu> + */ +//========================================================================== + + +#ifndef CIAO_MONITORH +#define CIAO_MONITORH + +#include "BaseMonitor.h" +#include "ace/Auto_Ptr.h" + +/** + * @namespace CIAO + * + * @brief The top level CIAO namespace + * + */ +namespace CIAO +{ + class ReceiverThread; + + /** + * @class CIAO_Monitor + * + * @brief The Monitor class + * + */ + class CIAO_Monitor : public MonitorBase + { + public: + + /** @function Constructor + */ + CIAO_Monitor (); + + /** + * This function is called by the controller to initialize + * parameters. + * @param domain The Initial Domain for this host + * @param target_manager TargetManager_ptr + * @param interval The time interval after whic updates need to be send. + */ + virtual int initialize_params ( + ::Deployment::Domain& domain, + ::Deployment::TargetManager_ptr target_manager, + int interval + ); + /** + * Destructor + */ + virtual ~CIAO_Monitor (); + + /** + * This method will starts up the Monitor in this case, + * @param orb The orb needed for resolving. + * @return -1 on error + */ + int start (CORBA::ORB_ptr orb); + + /** + * This method will stop the Monitor in this case + * @return -1 on error + */ + int stop (); + + /** + * This function retrieves the current Domain data + * @return -1 on error + */ + ::Deployment::Domain* get_current_data (); + + protected: + + /// The TargetManager Object to be sent to the RSSSubscriber .. + ::Deployment::TargetManager_ptr target_ptr_; + + /// The interval after which update is to be returned. + int interval_; + + /// The Domain data structure + auto_ptr <Deployment::Domain> current_domain_; + + /// The previous user cpu + long prev_user_cpu_; + + /// The previous user cpu low priority + long prev_user_cpu_low_; + + /// The previous system cpu + long prev_sys_cpu_; + + /// The previous idle time + long prev_idle_time_; + }; + +} // CIAO +#endif /* CIAO_MONITORH */ diff --git a/modules/CIAO/DAnCE/NodeManager/Monitor.mpc b/modules/CIAO/DAnCE/NodeManager/Monitor.mpc new file mode 100644 index 00000000000..9ccc91f0025 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/Monitor.mpc @@ -0,0 +1,28 @@ +// $Id$ + + +// MPC file for the Monitor + +project(*monitorlib): ciao_client_dnc, ciao_events_base_dnc { + after += CIAO_TargetManager_stub + includes += $(CIAO_ROOT)/DAnCE/TargetManager + sharedname = ciaomonlib + + libs += TargetManager_stub CIAO_Deployment_stub NodeManager_stub + + IDL_Files { + } + + Header_Files { + } + + Inline_Files { + } + + Template_Files { + } + + Source_Files { + CIAO_Monitor.cpp + } +} diff --git a/modules/CIAO/DAnCE/NodeManager/MonitorCB.cpp b/modules/CIAO/DAnCE/NodeManager/MonitorCB.cpp new file mode 100644 index 00000000000..56a789a76a3 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/MonitorCB.cpp @@ -0,0 +1,59 @@ +// $Id$ +//---------------------------------------------------------------------------------- +/** + * @file MonitorCB.cpp + * + * @brief The Monitor Update class + * + * The class which updates the resource data + * + * @author Nilabja Roy <nilabjar@dre.vanderbilt.edu> + */ +//---------------------------------------------------------------------------------- + +#include "MonitorCB.h" +#include "CIAO_common.h" + + +CIAO::MonitorCB::MonitorCB ( + CORBA::ORB_ptr orb, + Deployment::TargetManager_ptr target, + int interval) : + orb_ (orb), + target_mgr_ (target), + interval_ (interval) +{ +} + +int CIAO::MonitorCB::update_data (::Deployment::Domain& data) +{ + CORBA::StringSeq elements; + elements.length (0); + + // data to be updated ... + ::Deployment::DomainUpdateKind update_kind + = ::Deployment::UpdateAvailable; + + // The copy of the domain variable + ::Deployment::Domain_var domain + = new ::Deployment::Domain (data); + + try + { + if (CIAO::debug_level () > 20) + { + ACE_DEBUG ((LM_DEBUG , "CIAO::NM::MonitorCB::Making a call to update\n")); + } + target_mgr_->updateDomain (elements , domain , update_kind); + } + catch (CORBA::Exception& ) + { + //ACE_DEBUG ((LM_DEBUG, "CIAO::NM::MonitorCB::Unknown Exception\n")); + //ex._tao_print_exception ("NM::MonitorCB::updateDomain"); + } + catch (...) + { + // ignore + } + return 0; +} diff --git a/modules/CIAO/DAnCE/NodeManager/MonitorCB.h b/modules/CIAO/DAnCE/NodeManager/MonitorCB.h new file mode 100644 index 00000000000..777625bc9e0 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/MonitorCB.h @@ -0,0 +1,73 @@ +// $Id$ +//============================================================== +/** + * @file MonitorCB.h + * + * @brief The Monitor Callback Function + * + * This class updates data back to the Target Manager + * + * @author Nilabja Roy <nilabjar.vanderbilt.edu> +*/ +//============================================================== + +#ifndef MONITOR_CBH +#define MONITOR_CBH + +#include "ciao/Deployment_TargetManagerC.h" + +/** + * @namespace CIAO + * + * @brief The top level CIAO namespace + * + */ + +namespace CIAO +{ + /** + * @class MonitorCB + * + * @brief Updates data back to the TM. + * + */ + + class MonitorCB + { + public: + /** + * @param orb The ORB pointer + * @param target The TargetManager reference + * @param interval The time interval to sent update + */ + MonitorCB (CORBA::ORB_ptr orb, Deployment::TargetManager_ptr target, int interval); + /** + * This function is called by the monitor to + * update Domain data, which is then sent to + * TM. + * @param data Contains the updated Domain data + * @return int indicates success. + * @todo Check return value, seems not used at this moment + */ + int update_data (::Deployment::Domain& data); + private: + /// The ORB pointer + /// @todo Make this a _var + CORBA::ORB_ptr orb_; + + /// The Target Manager pointer to send back the + /// update + /// @todo Make this a _var + ::Deployment::TargetManager_ptr target_mgr_; + + /// The interval after which updates need to be send + int interval_; + + }; + + /// The Callback function pointer + typedef int (MonitorCB::*CallBack) (::Deployment::Domain &); + +} // CIAO namespace + +#endif /* MONITOR_CBH */ diff --git a/modules/CIAO/DAnCE/NodeManager/MonitorController.cpp b/modules/CIAO/DAnCE/NodeManager/MonitorController.cpp new file mode 100644 index 00000000000..76bd148613b --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/MonitorController.cpp @@ -0,0 +1,234 @@ +// $Id$ + +//---------------------------------------------------------------------------------- +/** + * @file MonitorController.cpp + * + * @brief The Monitor Controller implementation. + * + * This is the facade class for Monitor + * + * @author Nilabja Roy <nilabjar@dre.vanderbilt.edu> + */ +//---------------------------------------------------------------------------------- + +#include "MonitorController.h" +#include "BaseMonitor.h" +#include "MonitorCB.h" +#include "CIAO_common.h" + +#include "ace/Log_Msg.h" +#include "ace/DLL.h" +#include "ace/SString.h" + +#include "NodeManager_Impl.h" + +namespace CIAO +{ + typedef MonitorBase* (*MonitorFactory) (void); + + /// for the CIAO monitor + const char* monitor_lib_name = "ciaomonlib"; + + // The interval after which update will be sent. + // This value will sent by the EM in the later implementation + const int interval = 10; + + static const char* factory_func = "createMonitor"; +} + +CIAO::MonitorController::MonitorController ( + ::CORBA::ORB_ptr orb, + ::Deployment::Domain& domain, + ::Deployment::TargetManager_ptr target, + ::CIAO::NodeManager_Impl_Base* node_mgr + ) + : target_facet_i_ (::Deployment::TargetManager::_duplicate (target)), + terminate_flag_ (0), + orb_ (orb), + initial_domain_ (domain), + node_mgr_ (node_mgr), + monitor_cpu_usage_ (false), + add_component_pid_ (true) +{ +} + +int +CIAO::MonitorController::svc (void) +{ + // @todo. Investigate whether we can't use the reactor with a timer + // eventhandler for this monitor controller, would safe us a thread + ACE_DLL dll; + + // Forming the library name. + ACE_CString lib_name = ACE_DLL_PREFIX; + lib_name += monitor_lib_name; + int retval = dll.open (lib_name.c_str ()); + + if (retval != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%p", + "dll.open"), + -1); + } + + // Cast the void* to non-pointer type first - it's not legal to + // cast a pointer-to-object directly to a pointer-to-function. + void *void_ptr = dll.symbol (factory_func); + ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (void_ptr); + MonitorFactory factory = reinterpret_cast<MonitorFactory> (tmp); + + if (factory == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%p", + "dll.symbol"), + -1); + } + + { + ACE_TRACE ((LM_DEBUG, "Inside the init call\n")); + + // Creating the monitor object. + monitor_.reset ((MonitorBase*) factory ()); + monitor_->initialize_params (initial_domain_, + target_facet_i_.in (), + interval); + + + // Start the Monitor. + monitor_->start (orb_); + auto_ptr <CIAO::MonitorCB> monitor_callback (new CIAO::MonitorCB (orb_, + target_facet_i_.in (), + interval)); + + // check if cpu needs to be monitored or not + for (unsigned int i = 0;i < initial_domain_.node[0].resource.length ();i++) + { + if (!strcmp (initial_domain_.node[0].resource[i].name, "Processor")) + monitor_cpu_usage_ = true; + } + + // Wait for system to stabilize itself + ACE_OS::sleep (interval); + + // The loop in which UpdateData is called + while (!terminating ()) + { + + //ACE_DEBUG ((LM_DEBUG , "=The Terminate is %d\n", terminate_flag_)); + + + // if monitoring of cpu is enable , monitor , else dont do + // anything + ::Deployment::Domain* domain = 0; + + if (monitor_cpu_usage_) + domain = monitor_->get_current_data (); + else + domain = &initial_domain_; + + // ****** add component data ******************* + + NodeManager_Impl_Base::Component_Ids cids = + node_mgr_->get_component_detail (); + + // Here save the old resource length + int counter = domain->node[0].resource.length (); + + // if pid is already added , dont add + if (add_component_pid_) + { + // then add more resource element to the + // domain structure + // ACE_DEBUG ((LM_DEBUG , "Going to add CID/PID data\n")); + int new_res_size = domain->node[0].resource.length () + + cids.cid_seq_.size (); + + domain->node[0].resource.length (new_res_size); + + ACE_Unbounded_Set_Iterator<ACE_CString> iter (cids.cid_seq_); + + for (iter = cids.cid_seq_.begin (); + iter != cids.cid_seq_.end (); + iter++,counter++) + { + domain->node[0].resource[counter].name = + CORBA::string_dup ("Component"); + domain->node[0].resource[counter].resourceType.length (0); + + // Have one property for now + domain->node[0].resource[counter].property.length (1); + domain->node[0].resource[counter].property[0].name = + CORBA::string_dup ((*iter).c_str ()); + domain->node[0].resource[counter].property[0].kind = + ::Deployment::Quantity; + domain->node[0].resource[counter].property[0].dynamic = + 0; + domain->node[0].resource[counter].property[0].value <<= + CORBA::Long (cids.process_id_); + + // ACE_DEBUG ((LM_DEBUG , "The process id is [%d]\n", + // CORBA::Long (cids.process_id_))); + } + // set the add_component_pid_ to 0 + add_component_pid_ = false; + } + + //******add compoennt data + + monitor_callback->update_data (*domain); + + // data will be updated in intervals of 10 secs. + // in the latest version of spec , this value will + // come from Execution Manager + ACE_OS::sleep (interval); + + } + + monitor_->stop (); + } + + // here delete the monitor object before + // unloading the library + monitor_.reset (); + + // unload the library + dll.close (); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "CIAO::Monitor::Terminating Monitor\n")); + } + + return 0; +} + +CIAO::MonitorController::~MonitorController () +{ + terminate (); + wait (); +} + +void +CIAO::MonitorController::terminate () +{ + // make the terminate flag false + ACE_GUARD (ACE_SYNCH_MUTEX, + guard, + lock_); + + terminate_flag_ = true; +} + +bool +CIAO::MonitorController::terminating () +{ + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, + guard, + lock_, + 0); + + return terminate_flag_; +} diff --git a/modules/CIAO/DAnCE/NodeManager/MonitorController.h b/modules/CIAO/DAnCE/NodeManager/MonitorController.h new file mode 100644 index 00000000000..4da2dfb322f --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/MonitorController.h @@ -0,0 +1,123 @@ +// $Id$ + +//--------------------------------------------------------------------------------- +/** + * @file MonitorController.h + * + * @brief The Monitor Controller class. + * + * This class is invoked by the Nodemanager object and it + * in turn loads the proper Monitor which is strategised. + * + * @author Nilabja Roy + */ +//---------------------------------------------------------------------------------- +#ifndef MONITOR_CONTROLLER_H +#define MONITOR_CONTROLLER_H + +#include "NodeManager_svnt_export.h" +#include "Deployment_BaseC.h" + +#include "TargetManager/TargetManagerImplC.h" +#include "ace/Task.h" +#include "ace/Auto_Ptr.h" + +#include "ace/Synch_Traits.h" +#include "ace/Synch.h" + + +/** + * @namespace CIAO + * + * @brief The top level CIAO namespace + * + */ + +namespace CIAO +{ + + class MonitorBase; + + class NodeManager_Impl_Base; + + /** + * @class MonitorController + * + * @brief The Controller class + * + * Acts as a facade to the Monitor + * module + * + */ + class NodeManager_svnt_Export MonitorController : public ACE_Task_Base + { + public: + /** + * @brief The main function containing the + * entire activity. + * + * This function runs in the context of the + * thread + * @return int The status of the function + */ + int svc (void); + /** + * @brief The terminate function + * + * This function is called to terminate the + * thread + */ + void terminate (); + + + /// The Constructor. + MonitorController (CORBA::ORB_ptr orb, + ::Deployment::Domain& domain, + ::Deployment::TargetManager_ptr target, + ::CIAO::NodeManager_Impl_Base* node_mgr + ); + + ~MonitorController (); + protected: + + /** + * @brief returns the terminating flag + * @return bool The terminating state of the thread + */ + bool terminating (); + + /// The monitor object + auto_ptr <MonitorBase> monitor_; + + /// The TargetManagerImpl object + CIAO::TargetManagerImpl_var target_impl_cmp_; + + /// The TargetManager Facet .... + Deployment::TargetManager_var target_facet_i_; + + /// The terminate flag_ + bool terminate_flag_; + + /// Thread Mutex for synchronizing call + ACE_SYNCH_MUTEX lock_; + + /// the ORB pointer .. + /// @todo Make this a _var + CORBA::ORB_ptr orb_; + + /// The initial domain + ::Deployment::Domain initial_domain_; + + /// The Node Manager + ::CIAO::NodeManager_Impl_Base* node_mgr_; + + /// Flag tells ; what to monitor + bool monitor_cpu_usage_; + + /// To add component pid or not .. + bool add_component_pid_; + }; + +} // CIAO + +#endif diff --git a/modules/CIAO/DAnCE/NodeManager/NAM_Map.cpp b/modules/CIAO/DAnCE/NodeManager/NAM_Map.cpp new file mode 100644 index 00000000000..f3aebb307a2 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/NAM_Map.cpp @@ -0,0 +1,52 @@ +// $Id$ +#include "NAM_Map.h" +#include "ciao/CIAO_Config.h" +#include "ciao/CIAO_common.h" + +namespace CIAO +{ + NAM_Map::NAM_Map (void) + : map_ (CIAO_DEFAULT_MAP_SIZE) + { + } + + bool + NAM_Map::is_available (const ACE_CString &str) const + { + if (this->map_.find (str) == 0) + return true; + + return false; + } + + bool + NAM_Map::insert_nam (const ACE_CString &str, + const PortableServer::ObjectId &oid) + { + return (this->map_.bind (str, oid) == 0); + } + + ::PortableServer::ObjectId + NAM_Map::get_nam (const ACE_CString &str) + { + MAP::ENTRY *entry = 0; + + if (this->map_.find (str, entry) != 0) + return ::PortableServer::ObjectId (); + + return entry->int_id_.in (); + } + + bool + NAM_Map::remove_nam (const PortableServer::ObjectId &oid) + { + for (Iterator i = this->map_.begin (); + i != this->map_.end (); + ++i) + { + if ((*i).int_id_.in() == oid) + return this->map_.unbind ((*i).ext_id_) == 0; + } + return false; + } +} diff --git a/modules/CIAO/DAnCE/NodeManager/NAM_Map.h b/modules/CIAO/DAnCE/NodeManager/NAM_Map.h new file mode 100644 index 00000000000..4b398d51927 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/NAM_Map.h @@ -0,0 +1,72 @@ + /** + * @file NAM_Map.h + * @author Will Otte <wotte@dre.vanderbilt.edu> + * + * Map of NodeApplicationManagers, inspired by the DAM_Map + * class. + * + * $Id$ + */ + +#ifndef CIAO_NAM_MAP_H +#define CIAO_NAM_MAP_H + +#include /**/ "ace/pre.h" + +#include "tao/PortableServer/PortableServer.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 +{ + /** + * @class NAM_Map + * @brief Implementation of a map of NodeApplicationManagers. + * + * This table is used by the NodeManager to keep track of + * NAMs started for multiple assemblies. + */ + class NAM_Map + { + public: + /// Constructor + NAM_Map (void); + + /// Determine if there is a NAM associated with a UUID + bool is_available (const ACE_CString &str) const; + + /// Insert a NAM OID into the collection + bool insert_nam (const ACE_CString &str, + const PortableServer::ObjectId &oid); + + /// Get a specified NAM. + ::PortableServer::ObjectId + get_nam (const ACE_CString &str); + + /// Remove a nam from the map, given its oid. + bool remove_nam (const PortableServer::ObjectId &oid); + + private: + typedef + ACE_Hash_Map_Manager_Ex <ACE_CString, + ::PortableServer::ObjectId_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_NAM_MAP_H*/ diff --git a/modules/CIAO/DAnCE/NodeManager/NodeManager.mpc b/modules/CIAO/DAnCE/NodeManager/NodeManager.mpc new file mode 100644 index 00000000000..e58cc2d27d4 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/NodeManager.mpc @@ -0,0 +1,33 @@ +// -*- MPC -*- +// $Id$ + +//For static D&C, the NodeManager should be available as a linkable library +project(NodeManager_svnt): ciao_component_dnc, ciao_deployment_svnt, iortable, ifr_client, dance_extension_stub, ciao_server_dnc, ciao_nodeapplicationmanager, ciao_nodemanager_stub { + sharedname = NodeManager + dynamicflags = NODEMANAGER_SVNT_BUILD_DLL + + IDL_Files { + } + + Source_Files { + ../Interfaces/NodeManagerDaemonS.cpp + NodeManager_Impl.cpp + NAM_Map.cpp + MonitorController.cpp + MonitorCB.cpp + } +} + +project(NodeManager): ciao_server_dnc, iortable, ifr_client, dance_extension_stub, ciao_nodeapplicationmanager, ciao_targetmanager_stub, ciao_nodemanager_stub { + after += NodeManager_svnt + libs += NodeManager + exename = NodeManager + + IDL_Files { + } + + Source_Files { + Node_Manager.cpp + } +} + diff --git a/modules/CIAO/DAnCE/NodeManager/NodeManager_Impl.cpp b/modules/CIAO/DAnCE/NodeManager/NodeManager_Impl.cpp new file mode 100644 index 00000000000..5e8fea451cd --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/NodeManager_Impl.cpp @@ -0,0 +1,698 @@ +// $Id$ + +#include "NodeManager_Impl.h" +#include "DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.h" +#include "ace/Log_Msg.h" + +CIAO::NodeManager_Impl_Base::NodeManager_Impl_Base (const char *name, + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + const char * nodeapp_loc, + const char * nodeapp_options, + int spawn_delay) + ACE_THROW_SPEC ((CORBA::SystemException)) + : orb_ (CORBA::ORB::_duplicate (orb)), + poa_ (PortableServer::POA::_duplicate (poa)), + name_ (CORBA::string_dup (name)), + nodeapp_location_ (CORBA::string_dup (nodeapp_loc)), + nodeapp_options_ (CORBA::string_dup (nodeapp_options)), + callback_poa_ (PortableServer::POA::_nil ()), + spawn_delay_ (spawn_delay) +{ +} + +CIAO::NodeManager_Impl_Base::~NodeManager_Impl_Base () +{ +} + +void +CIAO::NodeManager_Impl_Base::init () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + try + { + // Create the call back poa for NAM. + PortableServer::POAManager_var mgr + = this->poa_->the_POAManager (); + + this->callback_poa_ = + this->poa_->create_POA ("callback_poa", + mgr.in (), + 0); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("NodeManager_Impl::init\t\n"); + throw; + } +} + +PortableServer::POA_ptr +CIAO::NodeManager_Impl_Base::_default_POA (void) +{ + return PortableServer::POA::_duplicate (this->poa_.in ()); +} + + +char * +CIAO::NodeManager_Impl_Base::name () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup (this->name_.in ()); +} + +void +CIAO::NodeManager_Impl_Base::shutdown () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + + this->orb_->shutdown (0); +} + +void +CIAO::NodeManager_Impl_Base::joinDomain (const Deployment::Domain & domain, + Deployment::TargetManager_ptr target, + Deployment::Logger_ptr) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // ACE_THROW (CORBA::NO_IMPLEMENT ()); + // Here start the Monitor + CIAO_TRACE("CIAO::NodeManager_Impl_Base::joinDomain"); + + ::Deployment::Domain this_domain = domain; + + monitor_controller_.reset ( + new MonitorController (orb_.in (), + this_domain, + target, + this)); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "Before Activate\n")); + } + + // Activate the Monitor Controller to + // start the monitoring + monitor_controller_->activate (); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "Monitor Activated\n")); + } +} + +void +CIAO::NodeManager_Impl_Base::leaveDomain () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Delete the monitor , this will also terminate the thread + monitor_controller_.reset (); +} + +CORBA::Long +CIAO::NodeManager_Impl_Base::set_priority ( + const char * plan_id, + const char * cid, + const ::Deployment::Sched_Params & nm_params + ) + ACE_THROW_SPEC ((::CORBA::SystemException)) + +{ + ACE_CString key (plan_id); + key += "@"; + key += this->name_.in (); + + if (CIAO::debug_level () > 10) + { + ACE_DEBUG ((LM_DEBUG , "Inside the set_priority\n")); + ACE_DEBUG ((LM_DEBUG , "pid = [%s] , cid = [%s]\n", key.c_str () , cid)); + } + + try { + CORBA::Object_var obj = + this->poa_->id_to_reference (this->map_.get_nam (key)); + + Deployment::NodeApplicationManager_var nam = + Deployment::NodeApplicationManager::_narrow (obj.in ()); + + return nam->set_priority (cid, nm_params); + } + catch (CORBA::Exception& ex) + { + + ex._tao_print_exception ("(%P|%t) NodeManager_Impl::set_priority ()\t\n"); + throw; + } +} + +::Components::FacetDescriptions * +CIAO::NodeManager_Impl_Base:: +get_all_facets (ACE_CString & name) +{ + Component_Facets_Map::ENTRY *entry = 0; + + if (this->comp_facets_map_.find (name.c_str (), entry) != 0) + { + ACE_ERROR ((LM_ERROR, "(%P|%t) - NodeManager_Impl_Base::get_all_facets - " + "No component with name [%s] was found in the NodeManager\n", name.c_str ())); + } + + CORBA::ULong const facet_len = entry->int_id_->length (); + + Components::FacetDescriptions_var retv; + ACE_NEW_RETURN (retv, + Components::FacetDescriptions, + 0); + + retv->length (facet_len); + + for (CORBA::ULong i = 0; i < facet_len; ++i) + { + retv[i] = entry->int_id_[i]; + } + + return retv._retn (); +} + +::Components::ConsumerDescriptions * +CIAO::NodeManager_Impl_Base:: +get_all_consumers (ACE_CString & name) +{ + Component_Consumers_Map::ENTRY *entry = 0; + + if (this->comp_consumers_map_.find (name.c_str (), entry) != 0) + { + ACE_ERROR ((LM_ERROR, "(%P|%t) - NodeManager_Impl_Base::get_all_facets - " + "Component [%s] was not found in the NodeManager\n", name.c_str ())); + } + + CORBA::ULong const consumer_len = entry->int_id_->length (); + + Components::ConsumerDescriptions_var retv; + ACE_NEW_RETURN (retv, + Components::ConsumerDescriptions, + 0); + + retv->length (consumer_len); + + for (CORBA::ULong i = 0; i < consumer_len; ++i) + { + retv[i] = entry->int_id_[i]; + } + + return retv._retn (); +} + +void +CIAO::NodeManager_Impl_Base:: +set_all_facets (ACE_CString &name, + const ::Components::FacetDescriptions_var & facets) +{ + this->comp_facets_map_.rebind (name, facets); +} + +void +CIAO::NodeManager_Impl_Base:: +set_all_consumers (ACE_CString &name, + const ::Components::ConsumerDescriptions_var & consumers) +{ + this->comp_consumers_map_.rebind (name, consumers); +} + + +Deployment::NodeApplicationManager_ptr +CIAO::NodeManager_Impl_Base:: +preparePlan (const Deployment::DeploymentPlan &plan) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError, + Deployment::PlanError)) +{ + CIAO_TRACE("CIAO::NodeManager_Impl::preparePlan"); + + if (! this->validate_plan (plan)) + { + ACE_ERROR ((LM_ERROR, "(%P|%t) NodeManager <%s>:prepare_plan:Plan_Error.\n", + plan.instance[0].node.in ())); + ACE_ERROR ((LM_ERROR, "(%P|%t) All component instances hosted in the " + "same component server must have the " + "same \"resourceName\" defined.\n")); + + ACE_THROW_RETURN (Deployment::PlanError (), + Deployment::NodeApplicationManager::_nil ()); + } + + // Update the reference count map based on the deployment plan input + for (CORBA::ULong i = 0; i < plan.instance.length (); ++i) + { + Reference_Count_Map::ENTRY *entry = 0; + if (this->ref_count_map_.find (plan.instance[i].name.in (), entry) != 0) + { + // Create a new entry, set the initial ref count "1", and insert to the map. + Ref_Count_Info new_entry; + new_entry.plan_uuid_ = plan.UUID.in (); + new_entry.count_ = 1; + this->ref_count_map_.bind (plan.instance[i].name.in (), new_entry); + } + else + { + // If the instance is within the same deployment plan, e.g., + // when ReDaC service is used, then just do nothing since it is NOT + // actually a shared component at all. + if (ACE_OS::strcmp (plan.UUID.in (), + entry->int_id_.plan_uuid_.c_str ()) == 0) + continue; + + // Otherwise, it is really a shared component, so let's increase + // the ref count by 1 + this->shared_components_.insert (plan.instance[i].name.in ()); + ++ entry->int_id_.count_; + } + } + + // Create/find NodeApplicationManager and set/reset plan on it + try + { + if (!this->map_.is_available (plan.UUID.in ())) + { + if (CIAO::debug_level () > 10) + { + ACE_DEBUG ((LM_DEBUG, "NM:prepare_plan: " + "creating a new NAM with UUID: %s\n", + plan.UUID.in ())); + } + + // Implementation undefined. + CIAO::NodeApplicationManager_Impl_Base *node_app_mgr = + this->create_node_app_manager (this->orb_.in (), this->poa_.in ()); + + PortableServer::ServantBase_var safe (node_app_mgr); + + //@@ Note: after the init call the servant ref count would + // become 2. so we can leave the safeservant along and be + // dead. Also note that I added + PortableServer::ObjectId_var oid = + node_app_mgr->init (this->nodeapp_location_.in (), + this->nodeapp_options_.in (), + this->spawn_delay_, + plan, + this->callback_poa_.in (), + this // pass in a copy of ourself (servant object) + ); + + this->map_.insert_nam (plan.UUID.in (), oid.in ()); + + CORBA::Object_var obj = + this->poa_->id_to_reference (this->map_.get_nam (plan.UUID.in ())); + + // We should inform NAM about "shared" components, so they + // won't be instantiated again + Deployment::NodeApplicationManager_var nam = + Deployment::NodeApplicationManager::_narrow (obj.in ()); + + // Convert the ACE Set into CORBA sequence, and make the remote invocation + Deployment::ComponentPlans_var shared = + this->get_shared_components_i (); + nam->set_shared_components (shared.in ()); + + // narrow should return a nil reference if it fails. + return Deployment::NodeApplicationManager::_narrow (nam.in ()); + } + else + { + if (CIAO::debug_level () > 10) + { + ACE_DEBUG ((LM_DEBUG, "NM:prepare_plan: reusing an old NAM " + "with UUID: %s\n", + plan.UUID.in ())); + } + + CORBA::Object_var obj = + this->poa_->id_to_reference (this->map_.get_nam (plan.UUID.in ())); + + Deployment::NodeApplicationManager_var nam = + Deployment::NodeApplicationManager::_narrow (obj.in ()); + + nam->reset_plan (plan); + + // Similarly, we should inform NAM about "shared" components, so + // they won't be instantiated again + Deployment::ComponentPlans_var shared = + this->get_shared_components_i (); + nam->set_shared_components (shared.in ()); + + // Potentially we could reset many other configuration settings + // such as command line options, service configuration file, etc. + return nam._retn (); + } + } + catch (const PortableServer::POA::ObjectNotActive&) + { + ACE_THROW_RETURN (Deployment::StartError (), + Deployment::NodeApplicationManager::_nil ()); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("(%P|%t) NodeManager_Impl::preparePlan\t\n"); + throw; + } + + return Deployment::NodeApplicationManager::_nil (); +} + +void +CIAO::NodeManager_Impl_Base::destroyManager +(Deployment::NodeApplicationManager_ptr manager) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError, + Deployment::InvalidReference)) +{ + CIAO_TRACE("CIAO::NodeManager_Impl::destroyManager"); + try + { + // Deactivate this object + PortableServer::ObjectId_var id = + this->poa_->reference_to_id (manager); + + if (!this->map_.remove_nam (id.in ())) + { + ACE_ERROR ((LM_ERROR, + "NodeManager_Impl::destroyManager: " + "Unable to remove object from map!\n")); + } + + this->poa_->deactivate_object (id.in ()); + } + catch (const PortableServer::POA::WrongAdapter&) + { + ACE_ERROR ((LM_ERROR, + "NodeManager_Impl::destroyManager: EXCEPTION - " + "Invalid reference passed to destroyManager\n")); + + throw ::Deployment::InvalidReference (); + } + catch (const PortableServer::POA::ObjectNotActive&) + { + ACE_ERROR ((LM_ERROR, + "NodeManager_Impl::destroyManager: EXCEPTION - " + " asked to destroy an already inactive object.\n")); + throw ::Deployment::InvalidReference (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("NodeManager_Impl::destroyManager\t\n"); + throw; + } +} + +void +CIAO::NodeManager_Impl_Base:: +destroyPlan (const Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::StopError)) +{ + // Update the reference counting map (subtract by 1 for each instance) + // If the ref count becomes 0, then remove this component, otherwise, + // we should remove the necesary bindings on this component specified + // in the deployment plan. + + // Clean up the cached "Facets" and "Consumers" map of the components + // if their ref count become 0 + CORBA::ULong const length = plan.instance.length (); + for (CORBA::ULong i = 0; i < length; ++i) + { + ACE_DEBUG ((LM_DEBUG, "NM_DP - forloop instance %s\n", + plan.instance[i].name.in ())); + + Reference_Count_Map::ENTRY *entry = 0; + if (this->ref_count_map_.find (plan.instance[i].name.in (), entry) == 0) + { + --entry->int_id_.count_; // decrease ref count by 1 + + if (entry->int_id_.count_ == 0) + { + // Remove this component from the shared set + ACE_DEBUG ((LM_DEBUG, "\tremoving shared...\n")); + this->shared_components_.remove (plan.instance[i].name.in ()); + ACE_DEBUG ((LM_DEBUG, "\tunbinding from the ref count map\n")); + // Unbind this component from the ref_count_map_ + this->ref_count_map_.unbind (plan.instance[i].name.in ()); + + ACE_DEBUG ((LM_DEBUG, "\tunbinding from the facet/consumer maps\n")); + // Unbind this component from the facet/consumer maps + if (this->comp_facets_map_.unbind ( + plan.instance[i].name.in ()) != 0 || + this->comp_consumers_map_.unbind ( + plan.instance[i].name.in ()) != 0) + { + throw + (Deployment::StopError ("NodeManager_Impl_Base::destroyPlan ", + "Unable to find component instance")); + } + } + } + } + + // Find the NAM from the map and invoke the destroyPlan() operation on + // it, which will actuall remove components and connections in this plan. + // If + CORBA::Object_var obj = + this->poa_->id_to_reference (this->map_.get_nam (plan.UUID.in ())); + + Deployment::NodeApplicationManager_var nam = + Deployment::NodeApplicationManager::_narrow (obj.in ()); + + + // Reset each NAM about the shared components information + Deployment::ComponentPlans_var shared = this->get_shared_components_i (); + nam->set_shared_components (shared.in ()); + + nam->destroyApplication (0); + + // @@ The problem is that we should NOT actually kill the NA process if + // there are some components that are shared by other plans. +} + +Deployment::ComponentPlans * +CIAO::NodeManager_Impl_Base:: +get_shared_components () + ACE_THROW_SPEC ((::CORBA::SystemException)) +{ + return this->get_shared_components_i (); +} + +Deployment::ComponentPlans * +CIAO::NodeManager_Impl_Base::get_shared_components_i (void) +{ + Deployment::ComponentPlans_var retv; + ACE_NEW_RETURN (retv, + Deployment::ComponentPlans, + 0); + retv->length (0); + + ACE_Unbounded_Set<ACE_CString>::iterator + end = this->shared_components_.end (); + + for (ACE_Unbounded_Set<ACE_CString>::iterator + iter = this->shared_components_.begin (); + iter != end; + ++iter) + { + CORBA::ULong const curr_len = retv->length (); + retv->length (curr_len + 1); + (*retv)[curr_len].name = (*iter).c_str (); + + // Fill in the plan_uuid information about this component, by + // searching in the ref_count_map_ + Reference_Count_Map::ENTRY *entry = 0; + if (this->ref_count_map_.find ((*iter).c_str (), entry) == 0) + { + // Get the plan_uuid_ info and populate the field + (*retv)[curr_len].plan_uuid = entry->int_id_.plan_uuid_.c_str (); + } + else + { + // should never happen + ACE_ERROR ((LM_ERROR, "Component [%s] in the list of shared component, " + "was not found in the NodeManager ref count map.\n", + (*iter).c_str ())); + } + } + + return retv._retn (); +} + + +CORBA::StringSeq * +CIAO::NodeManager_Impl_Base::shared_components_seq (void) +{ + CORBA::StringSeq * retv = 0; + ACE_NEW_RETURN (retv, CORBA::StringSeq, 0); + retv->length (0); + + // @todo rewrite to just set the length once and then copy the strings + // to reduce allocations + + ACE_Unbounded_Set<ACE_CString>::iterator end = this->shared_components_.end (); + for (ACE_Unbounded_Set<ACE_CString>::iterator + iter = this->shared_components_.begin (); + iter != end; + ++iter) + { + CORBA::ULong const curr_len = retv->length (); + retv->length (curr_len + 1); + (*retv)[curr_len] = (*iter).c_str (); + } + + return retv; +} + +bool +CIAO::NodeManager_Impl_Base:: +validate_plan (const Deployment::DeploymentPlan &plan) +{ + const char * resource_id = 0; + CORBA::ULong i = 0; + + // Update the name of ourself + this->name_ = plan.instance[0].node.in (); + + for (i = 0; i < plan.instance.length (); ++i) + { + if (plan.instance[i].deployedResource.length () != 0) + { + // Since the "name" field represents the server_resource_id, and + // the "resourceValue" field represents the policy_set_id, so we + // are checking to make sure that all component instances have + // the same server_resource_id. + + resource_id = + plan.instance[i].deployedResource[0].resourceName.in (); + break; + } + } + if (i == plan.instance.length ()) // No server resource id has been set for any instance + return true; + + for (i = 0; i < plan.instance.length (); ++i) + { + const char * my_resource_id = 0; + if (plan.instance[i].deployedResource.length () == 0) + { + continue; + } + else + { + my_resource_id = + plan.instance[i].deployedResource[0].resourceName.in ();; + if (ACE_OS::strcmp (resource_id, my_resource_id) != 0) + { + // Error, inconsistent server resource id found. + return false; + } + } + } + return true; +} + + +void CIAO::NodeManager_Impl_Base:: +push_component_id_info (Component_Ids comps) +{ + components_ = comps; +} + +CIAO::NodeManager_Impl_Base::Component_Ids +CIAO::NodeManager_Impl_Base:: +get_component_detail () +{ + return components_; +} + +CIAO::NodeManager_Impl::~NodeManager_Impl () +{ +} + +CIAO::NodeManager_Impl:: +NodeManager_Impl (const char *name, + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + const char * nodeapp_loc, + const char * nodeapp_options, + int spawn_delay) + : NodeManager_Impl_Base (name, orb, poa, nodeapp_loc, nodeapp_options, spawn_delay) +{} + + +::CIAO::NodeApplicationManager_Impl_Base * +CIAO::NodeManager_Impl:: +create_node_app_manager (CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CIAO::NodeApplicationManager_Impl_Base *app_mgr = 0; + ACE_NEW_THROW_EX (app_mgr, + CIAO::NodeApplicationManager_Impl (orb, + poa), + CORBA::NO_MEMORY ()); + return app_mgr; +} + +CIAO::Static_NodeManager_Impl::~Static_NodeManager_Impl () +{ +} + +CIAO::Static_NodeManager_Impl:: +Static_NodeManager_Impl (const char *name, + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + const char * nodeapp_loc, + const char * nodeapp_options, + int spawn_delay, + Static_Config_EntryPoints_Maps* static_config_entrypoints_maps) + : NodeManager_Impl_Base (name, orb, poa, nodeapp_loc, nodeapp_options, spawn_delay), + static_config_entrypoints_maps_ (static_config_entrypoints_maps) +{} + +::CIAO::NodeApplicationManager_Impl_Base * +CIAO::Static_NodeManager_Impl:: +create_node_app_manager (CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (CIAO::debug_level () > 10) + { + ACE_DEBUG ((LM_DEBUG, "creating static_node_app_manager\n")); + } + + CIAO::NodeApplicationManager_Impl_Base *app_mgr = 0; + ACE_NEW_THROW_EX (app_mgr, + CIAO::Static_NodeApplicationManager_Impl (orb, + poa, + this->static_config_entrypoints_maps_), + CORBA::NO_MEMORY ()); + return app_mgr; +} + +void +CIAO::Static_NodeManager_Impl::destroyManager +(Deployment::NodeApplicationManager_ptr manager) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError, + Deployment::InvalidReference)) +{ + CIAO_TRACE("CIAO::Static_NodeManager_Impl::destroyManager"); + try + { + CIAO::NodeManager_Impl_Base::destroyManager (manager); + + this->orb_->shutdown (0); + + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Static_NodeManager_Impl::destroyManager\t\n"); + throw; + } + +} diff --git a/modules/CIAO/DAnCE/NodeManager/NodeManager_Impl.h b/modules/CIAO/DAnCE/NodeManager/NodeManager_Impl.h new file mode 100644 index 00000000000..cea98f0fa91 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/NodeManager_Impl.h @@ -0,0 +1,341 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file NodeManager_Impl.h + * + * $Id$ + * + * This file contains servant implementation for Deployment:NodeManager + * interface. In the current design of the NodeManager, each NodeManager + * could manage one or more NodeApplication Managers. + * Though, the name intuitively suggests + * that there be one NodeManager for every node, our design, allows + * the end-user to have multiple components run on the same node. + * + * @author Arvind S. Krishna <arvindk@dre.vanderbilt.edu> + * @author Gan Deng <dengg@dre.vanderbilt.edu> + */ +//============================================================================= + + +#ifndef CIAO_NODEMANAGER_IMPL_H +#define CIAO_NODEMANAGER_IMPL_H +#include /**/ "ace/pre.h" + +#include "Interfaces/NodeManagerDaemonS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#if defined (_MSC_VER) +# pragma warning(push) +# pragma warning (disable:4250) +#endif /* _MSC_VER */ + +#include "NodeManager_svnt_export.h" +#include "NAM_Map.h" +#include "MonitorController.h" +#include "ace/Vector_T.h" + +namespace CIAO +{ + class NodeApplicationManager_Impl_Base; + + /** + * @class NodeManager_Impl + * + * @brief Servant implementation CIAO's daemon process control + * interface + * + * This class implements the CIAO:NodeManagerDaemon interface. + * + */ + class NodeManager_svnt_Export NodeManager_Impl_Base + : public virtual POA_CIAO::NodeManagerDaemon + { + public: + /// A struct that tracks the reference count of a particular + /// component as well as the "child_plan_uuid" where the component is + /// actually installed + typedef struct _ref_count_info + { + ACE_CString plan_uuid_; + size_t count_; + } Ref_Count_Info; + + /// Constructor + NodeManager_Impl_Base (const char *name, + CORBA::ORB_ptr orb, + PortableServer::POA_ptr p, + const char * nodeapp_loc, + const char* nodeapp_options, + int spawn_delay) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Initializes the NodeManager. + virtual void init () + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// POA operation.. + virtual PortableServer::POA_ptr _default_POA (void); + + /// CIAO::Daemon defined attributes/operations. + virtual char * name () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void shutdown () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void joinDomain (const Deployment::Domain & domain, + Deployment::TargetManager_ptr manager, + Deployment::Logger_ptr log + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void leaveDomain () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::Deployment::NodeApplicationManager_ptr + preparePlan (const Deployment::DeploymentPlan &plan) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StartError, + Deployment::PlanError)); + + virtual void + destroyManager (Deployment::NodeApplicationManager_ptr appManager) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError, + Deployment::InvalidReference)); + + /// CIAO specific extension, which is particularly useful for dealing with + /// shared components issue + virtual void destroyPlan (const Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC ((::CORBA::SystemException, + ::Deployment::StopError)); + + /// CIAO specific extension, return a set of shared components + virtual ::Deployment::ComponentPlans * + get_shared_components () + ACE_THROW_SPEC ((::CORBA::SystemException)); + + /// RACE specific extension. Modify the priority of a node application + /// process. + + virtual ::CORBA::Long + set_priority ( + const char * plan_id, + const char * cid, + const ::Deployment::Sched_Params & nm_params) + ACE_THROW_SPEC ((::CORBA::SystemException)); + + // ********* CIAO Specific Helper functions ************ + + virtual ::Components::FacetDescriptions * + get_all_facets (ACE_CString & name); + + virtual ::Components::ConsumerDescriptions * + get_all_consumers (ACE_CString & name); + + virtual void + set_all_facets (ACE_CString &name, + const ::Components::FacetDescriptions_var & facets); + + virtual void + set_all_consumers (ACE_CString &name, + const ::Components::ConsumerDescriptions_var & consumers); + + // ********* Function added for getting component ids... + + struct Component_Ids + { + ACE_Unbounded_Set <ACE_CString> cid_seq_; + pid_t process_id_; + }; + + virtual void push_component_id_info (Component_Ids comps); + + + Component_Ids get_component_detail (); + + private: + /// Validate the child deployment plan. In particular, we are + /// trying to verify that all the component instances within this + /// child deployment plan have the same "server_resource_id" + /// assigned. + bool validate_plan (const Deployment::DeploymentPlan &plan); + + protected: + /// Since this class is reference counted, making this + /// destructor protected to enforce proper memory managment + /// through the reference counting mechanism (i.e. to + /// disallow calling operator delete() on an instance of + /// this class. + virtual ~NodeManager_Impl_Base (void); + + virtual ::CIAO::NodeApplicationManager_Impl_Base * + create_node_app_manager (CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa) + ACE_THROW_SPEC ((CORBA::SystemException))=0; + + /// Actual implementation of the @c get_shared_components IDL operation + virtual ::Deployment::ComponentPlans * + get_shared_components_i (void); + + /// A helper method that convert ACE_Unbounded_Set to CORBA StringSeq + CORBA::StringSeq * shared_components_seq (void); + + /// Keep a pointer to the managing ORB serving this servant. + CORBA::ORB_var orb_; + + /// Keep a pointer to the managing POA. + PortableServer::POA_var poa_; + + /// My Canonical name. + CORBA::String_var name_; + + /// NodeApplication location + CORBA::String_var nodeapp_location_; + + /// NodeApplication options + CORBA::String_var nodeapp_options_; + + /// Cached callback POA. + PortableServer::POA_var callback_poa_; + + /// Spawn delay for the NodeAppMgr + int spawn_delay_; + + /// Cache reference of last NodeAppManager + /// Deployment::NodeApplicationManager_var manager_; + NAM_Map map_; + + /// A reference count map for the components installed on this node + /// @@TODO We should also keep the information about *where* the + /// component is installed + typedef + ACE_Hash_Map_Manager_Ex <ACE_CString, + Ref_Count_Info, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> Reference_Count_Map; + typedef Reference_Count_Map::iterator Ref_Count_Iterator; + + Reference_Count_Map ref_count_map_; + + /// A set to track the names of shared component instances + ACE_Unbounded_Set<ACE_CString> shared_components_; + + /// Cached object references of ports (facets/consumers) of + /// all components. This is useful for getting the port object + /// references of "shared components". The key in the map + /// is the component instance name. + typedef + ACE_Hash_Map_Manager_Ex <ACE_CString, + Components::FacetDescriptions_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> Component_Facets_Map; + + Component_Facets_Map comp_facets_map_; + + typedef + ACE_Hash_Map_Manager_Ex <ACE_CString, + Components::ConsumerDescriptions_var, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_Null_Mutex> Component_Consumers_Map; + + Component_Consumers_Map comp_consumers_map_; + + /// The MonitorController pointer + auto_ptr <MonitorController> monitor_controller_; + + /// The set of Components + Component_Ids components_; + }; + + + /** + * @class NodeManager_Impl + * + */ + class NodeManager_svnt_Export NodeManager_Impl + : public virtual NodeManager_Impl_Base + { + public: + + /// Constructor + NodeManager_Impl (const char *name, + CORBA::ORB_ptr orb, + PortableServer::POA_ptr p, + const char * nodeapp_loc, + const char * nodeapp_options, + int spawn_delay); + + protected: + /// Since this class is reference counted, making this + /// destructor protected to enforce proper memory managment + /// through the reference counting mechanism (i.e. to + /// disallow calling operator delete() on an instance of + /// this class. + virtual ~NodeManager_Impl (void); + + virtual ::CIAO::NodeApplicationManager_Impl_Base * + create_node_app_manager (CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa) + ACE_THROW_SPEC ((CORBA::SystemException)); + }; + + class NodeApplicationManager_Impl; + struct Static_Config_EntryPoints_Maps; + + /** + * @class Static_NodeManager_Impl + * + */ + class NodeManager_svnt_Export Static_NodeManager_Impl + : public virtual NodeManager_Impl_Base + { + public: + + /// Constructor + Static_NodeManager_Impl (const char *name, + CORBA::ORB_ptr orb, + PortableServer::POA_ptr p, + const char * nodeapp_loc, + const char * nodeapp_options, + int spawn_delay, + Static_Config_EntryPoints_Maps* static_config_entrypoints_maps + ); + + void destroyManager + (Deployment::NodeApplicationManager_ptr manager) + ACE_THROW_SPEC ((CORBA::SystemException, + Deployment::StopError, + Deployment::InvalidReference)); + + protected: + /// Since this class is reference counted, making this + /// destructor protected to enforce proper memory managment + /// through the reference counting mechanism (i.e. to + /// disallow calling operator delete() on an instance of + /// this class. + virtual ~Static_NodeManager_Impl (void); + + virtual ::CIAO::NodeApplicationManager_Impl_Base * + create_node_app_manager (CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa) + ACE_THROW_SPEC ((CORBA::SystemException)); + + Static_Config_EntryPoints_Maps* static_config_entrypoints_maps_; + }; + +} + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#include /**/ "ace/post.h" +#endif /* CIAO_NODEMANAGER_IMPL_H */ diff --git a/modules/CIAO/DAnCE/NodeManager/Node_Manager.cpp b/modules/CIAO/DAnCE/NodeManager/Node_Manager.cpp new file mode 100644 index 00000000000..7a10e719cc0 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/Node_Manager.cpp @@ -0,0 +1,288 @@ +// $Id$ + +#include "NodeManager_Impl.h" +#include "orbsvcs/CosNamingC.h" +#include "tao/IORTable/IORTable.h" +#include "ace/SString.h" +#include "ace/Read_Buffer.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/os_include/os_netdb.h" +#include "ciao/Server_init.h" +#include "ciao/CIAO_common.h" + +const char *ior_file_name_ = "nodedaemon.ior"; +char *nodeapp_location_ = 0; +const char *pid_file_name_ = 0; +bool write_to_ior_ = false; +bool register_with_ns_ = false; +int nodeapp_loc_ = 0; +int spawn_delay = 1; + +ACE_CString nodeapp_options_; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:c:m:s:d:na:p:z:"); + int c; + + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'z': + nodeapp_options_ += " -ORBDebugLevel "; + nodeapp_options_ += get_opts.opt_arg (); + break; + + case 'o': // Get the file name to write to. + ior_file_name_ = get_opts.opt_arg (); + write_to_ior_ = true; + break; + + case 'c': // Get the default svc.conf filename. + nodeapp_options_ += " -ORBSvcConf "; + nodeapp_options_ += get_opts.opt_arg (); + break; + + case 's': // Get the location to spawn the NodeApplication. + nodeapp_location_ = get_opts.opt_arg (); + nodeapp_loc_ = 1; + break; + + case 'a': // Nodeapplication arguments. + nodeapp_options_ = get_opts.opt_arg (); + break; + + case 'd': // Get the spawn delay argument. + spawn_delay = ACE_OS::atoi (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" + "-c <svc.conf file>\n" + "-n <use naming service>\n" + "-s <NodeApplication executable path>\n" + "-a <arguments to NodeApplication>\n" + "-d <spawn delay for nodeapplication>\n" + "-p <pid file>\n" + "\n", + argv [0]), + -1); + break; + } + } + + return 0; +} + +int +write_IOR (const char* ior) +{ + FILE* ior_output_file_ = + ACE_OS::fopen (ior_file_name_, "w"); + + if (ior_output_file_) + { + ACE_OS::fprintf (ior_output_file_, + "%s", + ior); + ACE_OS::fclose (ior_output_file_); + } + + return 0; +} + +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 (const char * name_context, + CORBA::ORB_ptr orb, + CIAO::NodeManagerDaemon_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); + name[0].id = name_context; + + try + { + // Register the servant with the Naming Service + naming_context->bind (name, obj); + } + catch (CosNaming::NamingContext::AlreadyBound &) + { + ACE_DEBUG ((LM_DEBUG, "Node_Manager.cpp: Name already bound, rebinding....\n")); + naming_context->rebind (name, obj); + } + + return true; +} + +int +main (int argc, char *argv[]) +{ + try + { + // Initialize orb + // @@TODO: Add error checking. There is absoluteley none. + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + ""); + + CIAO::Server_init (orb.in ()); + + if (parse_args (argc, argv) != 0) + return -1; + + // Check if NodeApplication executable location has been + // specified + if (! nodeapp_loc_) + { + ACE_DEBUG ((LM_DEBUG, "Use -s <NodeApplicationPath> to specify \ + executable path\n")); + ACE_OS::exit (1); + } + + // Get reference to Root POA. + CORBA::Object_var obj + = orb->resolve_initial_references ("RootPOA"); + + PortableServer::POA_var poa + = PortableServer::POA::_narrow (obj.in ()); + + CORBA::Object_var table_object = + orb->resolve_initial_references ("IORTable"); + + IORTable::Table_var adapter = + IORTable::Table::_narrow (table_object.in ()); + + if (CORBA::is_nil (adapter.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, "Nil IORTable\n"), -1); + } + + // Create and install the CIAO NodeManager servant + CIAO::NodeManager_Impl *node_manager_servant = 0; + ACE_NEW_RETURN (node_manager_servant, + CIAO::NodeManager_Impl("NodeManager", + orb.in (), + poa.in (), + nodeapp_location_, + nodeapp_options_.c_str (), + spawn_delay), + -1); + + PortableServer::ServantBase_var safe_daemon (node_manager_servant); + + node_manager_servant->init (); + + // Implicit activation + CIAO::NodeManagerDaemon_var node_manager = + node_manager_servant->_this (); + + CORBA::String_var str = + orb->object_to_string (node_manager.in ()); + + adapter->bind ("NodeManager", + str.in ()); + + if (write_to_ior_) + { + write_IOR (str.in ()); + } + else if (register_with_ns_) + { + char name [MAXHOSTNAMELEN + 1]; + + if (ACE_OS::hostname (name, MAXHOSTNAMELEN + 1) == -1) + { + ACE_ERROR ((LM_ERROR, + "gethostname call failed! \n")); + ACE_OS::exit (1); + } + + // Register this name with the Naming Service + (void) register_with_ns (name, + orb.in (), + node_manager.in ()); + } + + ACE_DEBUG ((LM_INFO, "CIAO_NodeManager IOR: %s\n", str.in ())); + + // Activate POA manager + PortableServer::POAManager_var mgr + = poa->the_POAManager (); + + mgr->activate (); + + // Here start the Monitor + /* + MonitorController* monitor_controller + = new MonitorController (orb); + + ACE_DEBUG ((LM_DEBUG , "Before Activate")); + monitor_controller->activate (); + ACE_DEBUG ((LM_DEBUG , "After Activate")); + */ + + // Finishing Deployment part + ACE_DEBUG ((LM_DEBUG, + "CIAO_NodeManager is running...\n")); + + write_pid (); + + // Run the main event loop for the ORB. + orb->run (); + + poa->destroy (1, 1); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("CIAO_NodeManager::main\t\n"); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "CIAO_NodeManager has closed\n")); + return 0; +} diff --git a/modules/CIAO/DAnCE/NodeManager/README b/modules/CIAO/DAnCE/NodeManager/README new file mode 100644 index 00000000000..dda9201e240 --- /dev/null +++ b/modules/CIAO/DAnCE/NodeManager/README @@ -0,0 +1,13 @@ +/** + +@page NodeManager README File + + CIAO's NodeManager implementation. NodeManager is the bootstraping +mechanism to create new NodeApplication on the localhost. We +currently depend on starting the NodeApplicationManager process on +some port of all the hosts that have NodeApplication install to +function properly. The port to run this daemon can be set by using the +TAO ORB options command of -ORBEndpoint <port>. This replaces the +earlier CIAO_Daemon implementation of CIAO as defined in the CCM +specification. +*/ diff --git a/modules/CIAO/DAnCE/Plan_Generator/PCVisitor.cpp b/modules/CIAO/DAnCE/Plan_Generator/PCVisitor.cpp new file mode 100644 index 00000000000..39bbb9bb434 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/PCVisitor.cpp @@ -0,0 +1,270 @@ +/* -*- C++ -*- */ + +//======================================================================== +/* + * @file PCVisitor.cpp + * + * $Id$ + * + * This file contains the implementation of the PackageConfiguration + * Visitor class PCVisitor which derives from PCVisitorBase. Each + * Visit function focuses on the functionality necessary to process + * the PackageConfiguration element which is passed to it as an argument + * and on dispatching the next sequence of calls in the correct order! + * + * This implementation takes a PackageConfiguration and tries to modify + * a DeploymentPlan bases on it by expanding the latter in width and depth + * simultaneously. At each level of the PackageConfiguration the + * PCVisitor first expands the DeploymentPlan vertically at the + * corrsponding level and then dispatches the children of the current + * PackageConfiguration element. This in turn might and most probably + * will cause another vertical expansion of the DeploymentPlan, however + * for a different element. This effect is produced due to the flattened + * structure of the DeploymentPlan. + * + * @author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + * Shanshan Jiang <shanshan.jiang@vanderbilt.edu> + */ +//======================================================================== + +#include "PCVisitorBase.h" +#include "PCVisitor.h" + +//Constructor +PCVisitor::PCVisitor (Deployment::DeploymentPlan &plan, + Deployment::PackageConfiguration &pc, + bool modify) + : PCVisitorBase (), + plan_ (plan), + pc_ (pc), + modify_ (modify), + last_impl_index_ (-1) +{ +} + +//entry point for the protected visitor to get it do start +//the visitation process +int PCVisitor::Visit () +{ + Accept (*this, this->pc_); + return last_impl_index_; +} + +// A whole slew of overloaded routines for different IDL +// data types part of the PackageConfiguration. + +void PCVisitor::Visit (Deployment::PackageConfiguration &pc) +{ + //visit the ComponentPackageDescription + if (pc.basePackage.length ()) + { + //currently no support for that anywhere + //for (size_t r = 0; r = pc.selectRequirement.length (); ++r); + + Accept (*this, pc.basePackage); + } + else + ACE_DEBUG ((LM_WARNING, + "[PCVisitor - PackageConfiguration] We currently " + "do NOT support package references, specializedConfigs", + "or imports!\n")); +} + +//ComponentPackageDescription descendents + +void PCVisitor::Visit (Deployment::ComponentPackageDescription &cpd) +{ + Accept (*this, cpd.realizes); + //for (size_t impl = 0; impl < cpd.implementation.length (); ++impl) + Accept (*this, cpd.implementation[0]); +} + + +void PCVisitor::Visit (Deployment::ComponentInterfaceDescription &) +{ + //Might want to populate this too once PICML starts supporting it +} + + +void PCVisitor::Visit (Deployment::PackagedComponentImplementation &pci) +{ + Accept (*this, pci.referencedImplementation); +} + + +void PCVisitor::Visit (Deployment::ComponentImplementationDescription &cid) +{ + if (cid.assemblyImpl.length ()) + Accept (*this, cid.assemblyImpl); + else + //;//Do nothing - monolithic component deployment not supported + Accept (*this, cid.monolithicImpl); +} + + +void PCVisitor::Visit (Deployment::ComponentAssemblyDescription &cad) +{ + //visit the SubcomponentInstantiationDescription + Accept (*this, cad.instance); + //visit the connections + Accept (*this, cad.connection); +} + + +void PCVisitor::Visit (Deployment::SubcomponentInstantiationDescription &sid) +{ + //visit the ComponentPackageDescription (again) + if (sid.basePackage.length ()) + { + Accept (*this, sid.basePackage); + } + else + ACE_DEBUG ((LM_WARNING, + "[PCVisitor - SubcomponentInstantiationDescription] ", + "We currently do NOT support package references, ", + "specializedConfigs or imports!\n")); +} + + +void PCVisitor::Visit (Deployment::MonolithicImplementationDescription &mid) +{ + if (!modify_) + { + //increase the implementation length by one + size_t impl_len = plan_.implementation.length (); + last_impl_index_ = impl_len; + plan_.implementation.length (impl_len + 1); + } + + //visit the NamedImplementationArtifacts + Accept (*this, mid.primaryArtifact); +} + + +void PCVisitor::Visit (Deployment::NamedImplementationArtifact &nia) +{ + if (!modify_) + { + //increase the artifact length by one + size_t arti_len = plan_.artifact.length (); + plan_.artifact.length (arti_len + 1); + + //set the name + plan_.artifact[arti_len].name = nia.name; + + //set the artifactRef of implementation + size_t last_mdd = plan_.implementation.length () - 1; + Deployment::MonolithicDeploymentDescription& mdd = plan_.implementation[last_mdd]; + size_t ref_len = mdd.artifactRef.length (); + mdd.artifactRef.length (ref_len + 1); + mdd.artifactRef[ref_len] = arti_len; + } + + //visit the actual ImplementationArtifactDescriptor + Accept (*this, nia.referencedArtifact); +} + + +void PCVisitor::Visit (Deployment::ImplementationArtifactDescription &iad) +{ + if (!modify_) + { + size_t last_arti = plan_.artifact.length (); + Deployment::ArtifactDeploymentDescription& add = plan_.artifact[last_arti - 1]; + + //set the location + size_t plan_loc_len = add.location.length (); + size_t num_loc = iad.location.length (); + for (size_t i = 0; i < num_loc; ++i) + { + add.location.length (plan_loc_len + 1); + add.location[plan_loc_len] = iad.location[i]; + ++plan_loc_len; + } + + //set the execParameter + update_execParameter (iad, add); + } + + else + { + size_t num_arti = plan_.artifact.length (); + for (size_t i = 0; i < num_arti; ++i) + { + if (ACE_OS::strstr (iad.location[0], plan_.artifact[i].location[0])) + plan_.artifact[i].location[0] = iad.location[0]; + } + } +} + + +//ComponentPackageReference descendents + +void PCVisitor::Visit (Deployment::ComponentPackageReference &) +{ + //not implemented +} + + +//properties + +void PCVisitor::Visit (Deployment::AssemblyPropertyMapping &) +{ +} + + +void PCVisitor::Visit (Deployment::Property &) +{ +} + + +//requirements & capabilities + +void PCVisitor::Visit (Deployment::Requirement &) +{ +} + + +void PCVisitor::Visit (Deployment::Capability &) +{ +} + + +void PCVisitor::Visit (Deployment::ImplementationRequirement &) +{ +} + + +void PCVisitor::Visit (Deployment::ImplementationDependency &) +{ +} + +//ports and connections + +void PCVisitor::Visit (Deployment::AssemblyConnectionDescription &) +{ +} + + +void PCVisitor::Visit (Deployment::SubcomponentPortEndpoint &) +{ +} + + +void PCVisitor::Visit (Deployment::ComponentExternalPortEndpoint &) +{ +} + +void PCVisitor:: +update_execParameter (Deployment::ImplementationArtifactDescription& iad, + Deployment::ArtifactDeploymentDescription& add) +{ + size_t num_execP = iad.execParameter.length (); + size_t execP_len = add.execParameter.length (); + for (size_t j = 0; j < num_execP; ++j) + { + add.execParameter.length (execP_len + 1); + add.execParameter[execP_len] = iad.execParameter[j]; + ++execP_len; + } +} diff --git a/modules/CIAO/DAnCE/Plan_Generator/PCVisitor.h b/modules/CIAO/DAnCE/Plan_Generator/PCVisitor.h new file mode 100644 index 00000000000..8417bc8a630 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/PCVisitor.h @@ -0,0 +1,128 @@ +/* -*- C++ -*- */ + +//======================================================================== +/** + * file PCVisitor.h + * + * $Id$ + * + * This file contains a number of Visitor classes which are used to + * traverse the PackageConfiguration element defined in the + * PackagingData.idl + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + * Shanshan Jiang <shanshan.jiang@vanderbilt.edu> + */ +//======================================================================== + +#ifndef PC_VISITOR_H +#define PC_VISITOR_H + +#include /**/ "ace/pre.h" +#include "PCVisitorBase.h" //for the base visitor + +//=========================================================================== +/** + * class PCVisitor + * + * This class is is the actual implementation for the PackageConfiguration + * Visitor. It derives from PCVisitorBase and overloads the functions which + * deal with single elements. Sequences are handled in the base class. + */ +//=========================================================================== + + +class PCVisitor : public PCVisitorBase +{ +public: + /// Constructor + PCVisitor (Deployment::DeploymentPlan &plan, + Deployment::PackageConfiguration &pc, + bool modify); + + /// Entry point to protected Visitor functions + int Visit (); + +protected: + /// A whole slew of overloaded routines for different IDL + /// data types part of the PackageConfiguration. + + virtual + void Visit (Deployment::PackageConfiguration &pc); + + //ComponentPackageDescription descendents + virtual + void Visit (Deployment::ComponentPackageDescription &cpd); + + virtual + void Visit (Deployment::ComponentInterfaceDescription &cid); + + virtual + void Visit (Deployment::PackagedComponentImplementation &pci); + + virtual + void Visit (Deployment::ComponentImplementationDescription &cid); + + virtual + void Visit (Deployment::ComponentAssemblyDescription &cad); + + virtual + void Visit (Deployment::SubcomponentInstantiationDescription &sid); + + virtual + void Visit (Deployment::MonolithicImplementationDescription &mid); + + virtual + void Visit (Deployment::NamedImplementationArtifact &nia); + + virtual + void Visit (Deployment::ImplementationArtifactDescription &iad); + + //ComponentPackageReference descendents + virtual + void Visit (Deployment::ComponentPackageReference &cpr); + + //properties + virtual + void Visit (Deployment::AssemblyPropertyMapping &apm); + + virtual + void Visit (Deployment::Property &property); + + //requirements & capabilities + virtual + void Visit (Deployment::Requirement &requirement); + + virtual + void Visit (Deployment::Capability &capability); + + virtual + void Visit (Deployment::ImplementationRequirement &ir); + + virtual + void Visit (Deployment::ImplementationDependency &id); + + //ports and connections + virtual + void Visit (Deployment::AssemblyConnectionDescription &acd); + + virtual + void Visit (Deployment::SubcomponentPortEndpoint &spe); + + virtual + void Visit (Deployment::ComponentExternalPortEndpoint &cepe); + +protected: + void update_execParameter (Deployment::ImplementationArtifactDescription& iad, + Deployment::ArtifactDeploymentDescription& add); + +private: + Deployment::DeploymentPlan& plan_; + Deployment::PackageConfiguration& pc_; + bool modify_; + int last_impl_index_; +}; + +#include /**/ "ace/post.h" + +#endif /* PC_VISITOR_H */ diff --git a/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.cpp b/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.cpp new file mode 100644 index 00000000000..c8ffc983095 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.cpp @@ -0,0 +1,28 @@ +/* -*- C++ -*- */ + +//======================================================================== +/* + * file PCVisitorBase.cpp + * + * $Id$ + * + * This file is a dummy which either includes the PCVisitorBase.inl or + * is ignored. + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + */ +//======================================================================== + +#include "PCVisitorBase.h" + +PCVisitorBase::PCVisitorBase (void) +{ +} + +PCVisitorBase::~PCVisitorBase (void) +{ +} + +#if !defined (__ACE_INLINE__) +#include "PCVisitorBase.inl" +#endif /* __ACE_INLINE__ */ diff --git a/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.h b/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.h new file mode 100644 index 00000000000..ac34dc4d261 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.h @@ -0,0 +1,171 @@ +/* -*- C++ -*- */ + +//======================================================================== +/** + * file PCVisitorBase.h + * + * $Id$ + * + * This file contains the virtual base class for the PackageConfiguration + * Visitor which is used to traverse the PackageConfiguration element + * defined in the PackagingData.idl. The PackageConfiguration has a + * number of sequence elements. This class actually implements the + * operations which involve sequences and delegates the calls to + * the operations which handle single elements from the sequence type. + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + */ +//======================================================================== + +#ifndef PC_VISITOR_BASE_H +#define PC_VISITOR_BASE_H + +#include /**/ "ace/pre.h" +#include "ciao/DeploymentC.h" + +//======================================================================== +/** + * class PCVisitorBase + * + * This class is a virtual base class for the PackageConfiguration Visitor + * The operation which deal with sequences are implemented here by means + * of the visit_sequence function above, in order to make the logic of + * derived classes easier to write. Writers of derived classes need only + * overload the functions which deal with single elements. Sequences are + * always handled here. + */ +//======================================================================== + + +class PCVisitorBase +{ +public: + /// Constructor + PCVisitorBase (void); + + /// Destructor + virtual ~PCVisitorBase (void); + + /// Function what dispatches sequences + template <typename SEQ> + friend void visit_sequence (SEQ &seq, PCVisitorBase& v); + + /// A whole slew of overloaded routines for different IDL + /// data types part of the PackageConfiguration. + + virtual + void Visit (Deployment::PackageConfiguration &pc) = 0; + void Visit (Deployment::PackageConfigurations &pcs); + + /// ComponentPackageDescription descendents + virtual + void Visit (Deployment::ComponentPackageDescription &cpd) = 0; + void Visit (Deployment::ComponentPackageDescriptions &cpds); + + virtual + void Visit (Deployment::ComponentInterfaceDescription &cid) = 0; + //void Visit (Deployment::ComponentInterfaceDescriptions &cids); + + virtual + void Visit (Deployment::PackagedComponentImplementation &pci) = 0; + void Visit (Deployment::PackagedComponentImplementations &pcis); + + virtual + void Visit (Deployment::ComponentImplementationDescription &cid) = 0; + //void Visit (Deployment::ComponentImplementationDescriptions &cids); + + virtual + void Visit (Deployment::ComponentAssemblyDescription &cad) = 0; + void Visit (Deployment::ComponentAssemblyDescriptions &cads); + + virtual + void Visit (Deployment::SubcomponentInstantiationDescription &sid) = 0; + void Visit (Deployment::SubcomponentInstantiationDescriptions &sids); + + virtual + void Visit (Deployment::MonolithicImplementationDescription &mid) = 0; + void Visit (Deployment::MonolithicImplementationDescriptions &mids); + + virtual + void Visit (Deployment::NamedImplementationArtifact &nia) = 0; + void Visit (Deployment::NamedImplementationArtifacts &nias); + + virtual + void Visit (Deployment::ImplementationArtifactDescription &iad) = 0; + //void Visit (Deployment::ImplementationArtifactDescriptions &iads); + + //ComponentPackageReference descendents + virtual + void Visit (Deployment::ComponentPackageReference &cpr) = 0; + void Visit (Deployment::ComponentPackageReferences &cprs); + + //properties + virtual + void Visit (Deployment::AssemblyPropertyMapping &apm) = 0; + void Visit (Deployment::AssemblyPropertyMappings &apms); + + virtual + void Visit (Deployment::Property &property) = 0; + void Visit (Deployment::Properties &properties); + + //requirements & capabilities + virtual + void Visit (Deployment::Requirement &requirement) = 0; + void Visit (Deployment::Requirements &requirements); + + virtual + void Visit (Deployment::Capability &capability) = 0; + void Visit (Deployment::Capabilities &capabilities); + + virtual + void Visit (Deployment::ImplementationRequirement &ir) = 0; + void Visit (Deployment::ImplementationRequirements &irs); + + virtual + void Visit (Deployment::ImplementationDependency &id) = 0; + void Visit (Deployment::ImplementationDependencies &ids); + + //ports and connections + virtual + void Visit (Deployment::AssemblyConnectionDescription &acd) = 0; + void Visit (Deployment::AssemblyConnectionDescriptions &acds); + + virtual + void Visit (Deployment::SubcomponentPortEndpoint &spe) = 0; + void Visit (Deployment::SubcomponentPortEndpoints &spes); + + virtual + void Visit (Deployment::ComponentExternalPortEndpoint &cepe) = 0; + void Visit (Deployment::ComponentExternalPortEndpoints &cepes); +}; + +template <typename T> +void Accept (PCVisitorBase &v, T& element_to_visit) +{ + v.Visit (element_to_visit); +} + +/** + * function - visit_sequence + * + * This function is used to handle sequences of elements where each + * element takes the form of a Visitor Node. + */ +template <typename SEQ> +void visit_sequence (SEQ &seq, PCVisitorBase& v) +{ + CORBA::ULong const size = seq.length (); + + for (CORBA::ULong i = 0; i < size; ++i) + { + Accept(v, seq[i]); + } +} + +#if defined (__ACE_INLINE__) +#include "PCVisitorBase.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* PC_VISITOR_BASE_H */ diff --git a/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.inl b/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.inl new file mode 100644 index 00000000000..955aefb7c4e --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/PCVisitorBase.inl @@ -0,0 +1,155 @@ +/* -*- C++ -*- */ + +//======================================================================== +/* + * file PCVisitorBase.inl + * + * $Id$ + * + * This file contains the implementation of the sequence-based + * PackageConfiguration Visitor functions. By implementing these + * we relieve developers of derived classes of the burden of handling + * the correct traversal of sequence-based elements. This implementation + * used the visit_sequence templatized function to do the heavy lifting. + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + */ +//======================================================================== + + +/// A whole slew of overloaded routines for different IDL +/// data types part of the PackageConfiguration. + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::PackageConfigurations &pcs) +{ + visit_sequence (pcs, *this); +} + +//ComponentPackageDescription descendents + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::ComponentPackageDescriptions &cpds) +{ + visit_sequence (cpds, *this); +} + +//NOT a member of Deployment + +//ACE_INLINE void PCVisitorBase::Visit +// (Deployment::ComponentInterfaceDescriptions &cids) +//{ +// visit_sequence (cids, *this); +//} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::PackagedComponentImplementations &pcis) +{ + visit_sequence (pcis, *this); +} + +//NOT a member of Deployment + +//ACE_INLINE void PCVisitorBase::Visit +// (Deployment::ComponentImplementationDescriptions &cids) +//{ +// visit_sequence (cids, *this); +//} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::ComponentAssemblyDescriptions &cads) +{ + visit_sequence (cads, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::SubcomponentInstantiationDescriptions &sids) +{ + visit_sequence (sids, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::MonolithicImplementationDescriptions &mids) +{ + visit_sequence (mids, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::NamedImplementationArtifacts &nias) +{ + visit_sequence (nias, *this); +} + +//ACE_INLINE void PCVisitorBase::Visit +// (Deployment::ImplementationArtifactDescriptions &iads) +//{ +// visit_sequence (iads, *this); +//} + +//ComponentPackageReference descendents + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::ComponentPackageReferences &cprs) +{ + visit_sequence (cprs, *this); +} + +//properties + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::AssemblyPropertyMappings &apms) +{ + visit_sequence (apms, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::Properties &properties) +{ + visit_sequence (properties, *this); +} + +//requirements & capabilities + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::Requirements &requirements) +{ + visit_sequence (requirements, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::Capabilities &capabilities) +{ + visit_sequence (capabilities, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::ImplementationRequirements &irs) +{ + visit_sequence (irs, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::ImplementationDependencies &ids) +{ + visit_sequence (ids, *this); +} + +//ports and connections + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::AssemblyConnectionDescriptions &acds) +{ + visit_sequence (acds, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::SubcomponentPortEndpoints &spes) +{ + visit_sequence (spes, *this); +} + +ACE_INLINE void PCVisitorBase::Visit +(Deployment::ComponentExternalPortEndpoints &cepes) +{ + visit_sequence (cepes, *this); +} diff --git a/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator.mpc b/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator.mpc new file mode 100644 index 00000000000..ac3026061e3 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator.mpc @@ -0,0 +1,22 @@ +// -*- MPC -*- +//$Id$ + +project (Plan_Generator): ciao_component_dnc { + sharedname = Plan_Generator + after += RepositoryManager + + dynamicflags = PLAN_GENERATOR_IMPL_BUILD_DLL + + Source_Files { + Plan_Generator_Impl.cpp + PCVisitorBase.cpp + PCVisitor.cpp + } + + Header_Files { + Plan_Generator_Impl.h + PCVisitor.h + PCVisitorBase.h + Plan_Generator_Impl_Export.h + } +} diff --git a/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl.cpp b/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl.cpp new file mode 100644 index 00000000000..a1e5831e0af --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl.cpp @@ -0,0 +1,153 @@ +/** + * $Id$ + * @file Plan_Generator_Impl.cpp + * @author Shanshan Jiang <shanshan.jiang@vanderbilt.edu> + */ + +#include "Plan_Generator_Impl.h" +#include "orbsvcs/CosNamingC.h" +#include "PCVisitor.h" +#include "PCVisitorBase.h" + +namespace CIAO +{ + namespace Plan_Generator + { + // @todo make this a private method + static CORBA::Object_ptr + fetch_reference_naming (CORBA::ORB_ptr orb, + const char *repoman_name = 0) + { + CORBA::Object_var tmp = + orb->resolve_initial_references ("NameService"); + + CosNaming::NamingContext_var pns = + CosNaming::NamingContext::_narrow (tmp.in ()); + + if (CORBA::is_nil (pns.in ())) + { + return CORBA::Object::_nil (); + } + + CosNaming::Name name (1); + name.length (1); + + name[0].id = CORBA::string_dup (repoman_name); + + return pns->resolve (name); + } + + Plan_Generator_i::Plan_Generator_i () + : rm_ () + { + } + + bool + Plan_Generator_i::init (CORBA::ORB_ptr orb, + bool rm_use_naming, + const char *rm_name) + { + CORBA::Object_var obj; + + if (rm_use_naming) + { + obj = fetch_reference_naming (orb, rm_name); + } + else + { + obj = orb->string_to_object (rm_name); + } + + this->rm_ = Deployment::RepositoryManager::_narrow (obj.in ()); + + if (CORBA::is_nil (this->rm_.in ())) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) CIAO_PlanGenerator: nil Repository " + "Manager reference, narrow failed\n")); + return false; + } + + return true; + } + + bool + Plan_Generator_i::generate_plan (Deployment::DeploymentPlan &plan, + const char *package_uri, + bool use_package_name) + { + if (CORBA::is_nil (rm_.in ())) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) CIAO_Repoman: nil Execution\n")); + return false; + } + + ::Deployment::PackageConfiguration_var pc; + + ACE_TCHAR package[PACKAGE_NAME_LEN]; + + size_t length = ACE_OS::strlen (package_uri); + + size_t pos1 = 0; + size_t pos2 = ACE_OS::strcspn (package_uri + pos1, "+"); + + while (pos1 < length) + { + ACE_OS::strsncpy (package, package_uri + pos1, pos2 + 1); + + if (use_package_name) + { + pc = this->rm_->findPackageByName (package); + + PCVisitor pcv (plan, *pc, true); + pcv.Visit (); + } + else + { + CORBA::StringSeq_var seq = this->rm_->findNamesByType (package); + + for (CORBA::ULong i = 0; i < seq->length (); ++i) + { + pc = this->rm_->findPackageByName (seq[i]); + + PCVisitor pcv (plan, *pc, true); + pcv.Visit (); + } + } + + pos1 += pos2 + 1; + pos2 = ACE_OS::strcspn (package_uri + pos1, "+"); + } + + return true; + } + + bool + Plan_Generator_i::generate_plan (Deployment::DeploymentPlan &plan, + const char *specific_type, + int &index) + { + if (CORBA::is_nil (rm_.in ())) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) CIAO_Repoman: nil Execution\n")); + return false; + } + + ::Deployment::PackageConfiguration_var pc; + + CORBA::StringSeq_var seq = rm_->findNamesByType (specific_type); + for (CORBA::ULong i = 0; i < seq->length (); ++i) + { + pc = rm_->findPackageByName (seq[i]); + + PCVisitor pcv (plan, *pc, false); + index = pcv.Visit (); + } + + return true; + } + + } +} diff --git a/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl.h b/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl.h new file mode 100644 index 00000000000..3fbfef3a9c6 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl.h @@ -0,0 +1,78 @@ +/** + * $Id$ + * @file Plan_Generator_Impl.h + * @author Shanshan Jiang <shanshan.jiang@vanderbilt.edu> + * + * Contains the Plan_Generator_i class, which can be used to generate/modify + * DeploymentPlans. + */ + +#ifndef PLAN_GENERATOR_IMPL_H +#define PLAN_GENERATOR_IMPL_H + +#include "ciao/Deployment_RepositoryManagerC.h" +#include "Plan_Generator_Impl_Export.h" + +namespace CIAO +{ + namespace Plan_Generator + { + const size_t PACKAGE_NAME_LEN = 1024; + + /** + * @class Plan_Generator_i + * @brief This class generates or modifies deployment plans. + */ + class Plan_Generator_Impl_Export Plan_Generator_i + { + public: + Plan_Generator_i (); + + /** + * @fn init + * @brief Get the proper Repoman, using naming service or ior file. + * @param orb + * @param rm_use_naming Whether use naming service or not. + * @param rm_name The name of the Repoman. + * @returns a boolean denoting if this operation is successful or not. + */ + bool init (CORBA::ORB_ptr orb, + bool rm_use_naming = 0, + const char *rm_name = 0); + + /** + * @fn generate_plan + * @brief Use the package name(s) or type(s) to get the PackageConfiguration + * provided by Repoman; and then use the PackageConfiguration to + * modify the location of all the artifacts in DeploymentPlan. + * @param plan A DeploymentPlan that need to be updated. + * @param package_uri The package name(s) or type(s). + * @param use_package_name Use package name(s) or type(s). + * @returns a boolean denoting if this operation is successful or not. + */ + bool generate_plan (Deployment::DeploymentPlan &plan, + const char *package_uri, + bool use_package_name); + + /** + * @fn generate_plan + * @brief Use the specific type of a package to get the PackageConfiguration + * provided by Repoman; and then use the PackageConfiguration to + * generate the implementation and artifact fields in DeploymentPlan. + * @param plan A DeploymentPlan that need to be updated. + * @param package_uri The package specific type. + * @param index The index of the newly generated implementation and artifact fields. + * @returns a boolean denoting if this operation is successful or not. + */ + bool generate_plan (Deployment::DeploymentPlan &plan, + const char *specific_type, + int &index); + + private: + Deployment::RepositoryManager_var rm_; + }; + + } +} + +#endif /* PLAN_GENERATOR_IMPL_H */ diff --git a/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl_Export.h b/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl_Export.h new file mode 100644 index 00000000000..fd120ff7b73 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Generator/Plan_Generator_Impl_Export.h @@ -0,0 +1,58 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl Plan_Generator_Impl +// ------------------------------ +#ifndef PLAN_GENERATOR_IMPL_EXPORT_H +#define PLAN_GENERATOR_IMPL_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (PLAN_GENERATOR_IMPL_HAS_DLL) +# define PLAN_GENERATOR_IMPL_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && PLAN_GENERATOR_IMPL_HAS_DLL */ + +#if !defined (PLAN_GENERATOR_IMPL_HAS_DLL) +# define PLAN_GENERATOR_IMPL_HAS_DLL 1 +#endif /* ! PLAN_GENERATOR_IMPL_HAS_DLL */ + +#if defined (PLAN_GENERATOR_IMPL_HAS_DLL) && (PLAN_GENERATOR_IMPL_HAS_DLL == 1) +# if defined (PLAN_GENERATOR_IMPL_BUILD_DLL) +# define Plan_Generator_Impl_Export ACE_Proper_Export_Flag +# define PLAN_GENERATOR_IMPL_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define PLAN_GENERATOR_IMPL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* PLAN_GENERATOR_IMPL_BUILD_DLL */ +# define Plan_Generator_Impl_Export ACE_Proper_Import_Flag +# define PLAN_GENERATOR_IMPL_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define PLAN_GENERATOR_IMPL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* PLAN_GENERATOR_IMPL_BUILD_DLL */ +#else /* PLAN_GENERATOR_IMPL_HAS_DLL == 1 */ +# define Plan_Generator_Impl_Export +# define PLAN_GENERATOR_IMPL_SINGLETON_DECLARATION(T) +# define PLAN_GENERATOR_IMPL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* PLAN_GENERATOR_IMPL_HAS_DLL == 1 */ + +// Set PLAN_GENERATOR_IMPL_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (PLAN_GENERATOR_IMPL_NTRACE) +# if (ACE_NTRACE == 1) +# define PLAN_GENERATOR_IMPL_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define PLAN_GENERATOR_IMPL_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !PLAN_GENERATOR_IMPL_NTRACE */ + +#if (PLAN_GENERATOR_IMPL_NTRACE == 1) +# define PLAN_GENERATOR_IMPL_TRACE(X) +#else /* (PLAN_GENERATOR_IMPL_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define PLAN_GENERATOR_IMPL_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (PLAN_GENERATOR_IMPL_NTRACE == 1) */ + +#endif /* PLAN_GENERATOR_IMPL_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher.cpp b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher.cpp new file mode 100644 index 00000000000..d5233cf870c --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher.cpp @@ -0,0 +1,327 @@ +// $Id$ + +#include "Plan_Launcher_Impl.h" + +#include "ace/OS.h" +#include "ace/Get_Opt.h" +#include <iostream> + +#include "DAnCE/Interfaces/ExecutionManagerDaemonC.h" + +namespace CIAO +{ + namespace Plan_Launcher + { + // deployment plan URL + const char* deployment_plan_url = 0; + bool use_package_name = true; + const char* package_names = 0; + const char* package_types = 0; + const char* new_deployment_plan_url = 0; + const char* plan_uuid = 0; + bool em_use_naming = false; + const char* em_ior_file = "file://em.ior"; + bool rm_use_naming = false; + bool use_repoman = false; + const char* rm_ior_file = "file://rm.ior"; + const char* repoman_name_ = "RepositoryManager"; + const char* dap_ior_filename = 0; + const char* dap_ior = 0; + + enum mode_type { + pl_mode_start, + pl_mode_interactive, + pl_mode_stop_by_dam, + pl_mode_stop_by_uuid, + pl_mode_redeployment + }; + + // default mode + mode_type mode = pl_mode_interactive; + + static void + usage (const ACE_TCHAR* program) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("[(%P|%t) Executor] Usage: %s\n") + ACE_TEXT ("-a <PACKAGE_NAMES>\n") + ACE_TEXT ("-e <PACKAGE_TYPES>\n") + ACE_TEXT ("-p <DEPLOYMENT_PLAN_URL>\n") + ACE_TEXT ("-n : Use naming service to fetch EM") + ACE_TEXT ("-k <EXECUTION_MANAGER_IOR>") + ACE_TEXT (" : Default file://em.ior\n") + ACE_TEXT ("-l <REPOSITORY_MANAGER_IOR>") + ACE_TEXT (" : Default file://rm.ior\n") + ACE_TEXT ("-v <REPOSITORY_MANAGER_NAME>: Use naming service to fetch RM with the given name") + ACE_TEXT (" : Default RepositoryManager\n") + ACE_TEXT ("-t <PLAN_UUID>\n") + ACE_TEXT ("-o <DOMAIN_APPLICATION_MANAGER_IOR_OUTPUT_FILE>\n") + ACE_TEXT ("-i <DOMAIN_APPLICATION_MANAGER_IOR_FOR_INPUT>\n") + ACE_TEXT ("-r <NEW_PLAN_DESCRIPTOR_FOR_REDEPLOYMENT>\n") + ACE_TEXT ("-h : Show this usage information\n"), + program)); + } + + static bool + parse_args (int argc, + ACE_TCHAR *argv[]) + { + ACE_Get_Opt get_opt (argc, + argv, + ACE_TEXT ("a:e:p:nk:l:v:t:o:i:r:h")); + int c; + + while ((c = get_opt ()) != EOF) + { + switch (c) + { + case 'a': + package_names = get_opt.opt_arg (); + use_package_name = true; + break; + case 'e': + package_types = get_opt.opt_arg (); + use_package_name = false; + break; + case 'p': + deployment_plan_url = get_opt.opt_arg (); + break; + case 'n': + em_use_naming = true; + break; + case 'k': + em_ior_file = get_opt.opt_arg (); + break; + case 'l': + use_repoman = true; + rm_ior_file = get_opt.opt_arg (); + break; + case 'v': + use_repoman = true; + rm_use_naming = true; + repoman_name_ = get_opt.opt_arg (); + break; + case 'o': + dap_ior_filename = get_opt.opt_arg (); + mode = pl_mode_start; + break; + case 'i': + dap_ior = get_opt.opt_arg (); + mode = pl_mode_stop_by_dam; + break; + case 't': + plan_uuid = get_opt.opt_arg (); + mode = pl_mode_stop_by_uuid; + break; + case 'r': + new_deployment_plan_url = get_opt.opt_arg (); + mode = pl_mode_redeployment; + break; + case 'h': + default: + usage(argv[0]); + return false; + } + } + + if ((mode != pl_mode_stop_by_dam) && + (mode != pl_mode_stop_by_uuid) && + (package_names == 0) && + (package_types == 0) && + (deployment_plan_url == 0) && + (new_deployment_plan_url == 0)) + { + usage (argv[0]); + return false; + } + + return true; + } + + static ::Deployment::DomainApplicationManager_ptr + read_dap_ior (CORBA::ORB_ptr orb) + { + CORBA::Object_var obj = orb->string_to_object (dap_ior); + return + Deployment::DomainApplicationManager::_narrow (obj.in ()); + } + + static int + write_dap_ior (CORBA::ORB_ptr orb, + ::Deployment::DomainApplicationManager_ptr dap) + { + CORBA::String_var ior = orb->object_to_string (dap); + + FILE* ior_output_file = ACE_OS::fopen (dap_ior_filename, "w"); + + if (ior_output_file) + { + ACE_OS::fprintf (ior_output_file, "%s", ior.in ()); + ACE_OS::fclose (ior_output_file); + + return 0; + } + + return -1; + } + + static int + run_main_implementation (int argc, char *argv[]) + { + + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, + argv, + ""); + + if (parse_args (argc, argv) == false) + return -1; + + Plan_Launcher_i launcher; + + if (!launcher.init (em_use_naming ? 0 : em_ior_file, + orb.in (), + use_repoman, + rm_use_naming, + rm_use_naming ? repoman_name_ : rm_ior_file)) + { + ACE_ERROR ((LM_ERROR, "(%P|%t) Plan_Launcher: Error initializing the EM.\n")); + return -1; + } + + ::Deployment::DomainApplicationManager_var dapp_mgr; + + if (mode == pl_mode_start || mode == pl_mode_interactive) // initial deployment + { + CORBA::String_var uuid; + + if (package_names != 0) + uuid = launcher.launch_plan (deployment_plan_url, + package_names, + use_package_name, + use_repoman); + else + uuid = launcher.launch_plan (deployment_plan_url, + package_types, + use_package_name, + use_repoman); + + if (uuid.in () == 0) + { + ACE_ERROR ((LM_ERROR, "(%P|%t) Plan_Launcher: Error launching plan\n")); + return -1; + } + + ACE_DEBUG ((LM_DEBUG, "Plan_Launcher returned UUID is %s\n", uuid.in ())); + dapp_mgr = launcher.get_dam (uuid.in ()); + + // Write out DAM ior if requested + if (mode == pl_mode_start) + { + write_dap_ior (orb.in (), dapp_mgr.in ()); + } + else // if (pl_mode_interactive) + { + ACE_DEBUG ((LM_DEBUG, + "Press <Enter> to tear down application\n")); + char dummy [256]; + std::cin.getline (dummy, 256); + + // Tear down the assembly + ACE_DEBUG ((LM_DEBUG, + "Plan_Launcher: destroy the application.....\n")); + if (! launcher.teardown_plan (uuid)) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) CIAO_PlanLauncher:tear down assembly failed: " + "unkonw plan uuid.\n")); + } + } + else if (mode == pl_mode_redeployment && new_deployment_plan_url != 0) // do redeployment + { + ACE_DEBUG ((LM_DEBUG, + "Plan_Launcher: reconfigure application assembly.....\n")); + + CORBA::String_var uuid; + + if (package_names != 0) + uuid = launcher.re_launch_plan (new_deployment_plan_url, + package_names, + use_package_name, + use_repoman); + else + uuid = launcher.re_launch_plan (new_deployment_plan_url, + package_types, + use_package_name, + use_repoman); + + if (uuid.in () == 0) + { + ACE_ERROR ((LM_ERROR, "(%P|%t) Plan_Launcher: Error re-launching plan\n")); + return -1; + } + } + else if (mode == pl_mode_stop_by_dam) // tear down by DAM + { + dapp_mgr = read_dap_ior (orb.in ()); + + if (CORBA::is_nil (dapp_mgr.in ())) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) CIAO_PlanLauncher:tear down assembly failed: " + "nil DomainApplicationManager reference\n")); + return -1; + } + + // Tear down the assembly + ACE_DEBUG ((LM_DEBUG, + "Plan_Launcher: destroy the application.....\n")); + launcher.teardown_plan (dapp_mgr.in ()); + } + else if (mode == pl_mode_stop_by_uuid) // tear down by plan_uuid + { + // Tear down the assembly + ACE_DEBUG ((LM_DEBUG, + "Plan_Launcher: destroy the application.....\n")); + if (! launcher.teardown_plan (plan_uuid)) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) CIAO_PlanLauncher:tear down assembly failed: " + "unkown plan uuid.\n")); + } + } + + orb->destroy (); + } + catch (const Plan_Launcher_i::Deployment_Failure&) + { + ACE_ERROR ((LM_ERROR, + "Deployment failed. Plan_Launcher exiting.\n")); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("(%P|%t) Plan_Launcher: "); + + return -1; + } + catch (...) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) Plan_Launcher: Unknown exception.\n")); + return -1; + } + + return 0; + } + } +} + +using namespace CIAO::Plan_Launcher; + +int +ACE_TMAIN (int argc, + ACE_TCHAR *argv[]) +{ + return run_main_implementation (argc, argv); +} diff --git a/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher.mpc b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher.mpc new file mode 100644 index 00000000000..f264738108a --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher.mpc @@ -0,0 +1,33 @@ +// -*- MPC -*- +// $Id$ + +project(Plan_Launcher_Impl) : ciao_servant_dnc, ciao_config_handlers, ciao_executionmanager_stub, ciao_plan_generator { + sharedname = Plan_Launcher_Impl + + dynamicflags = PLAN_LAUNCHER_IMPL_BUILD_DLL + + Source_Files { + ../ExecutionManager/DAM_Map.cpp + Plan_Launcher_Impl.cpp + } + + Header_Files { + ../ExecutionManager/DAM_Map.h + Plan_Launcher_Impl.h + Plan_Launcher_Impl_Export.h + } +} + +project(Plan_Launcher) : ciao_server_dnc, ciao_config_handlers, ciao_executionmanager_stub, ciao_plan_generator { + exename = plan_launcher + + after += Plan_Launcher_Impl + libs += Plan_Launcher_Impl + + Source_Files { + Plan_Launcher.cpp + } + + Header_Files { + } +} diff --git a/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl.cpp b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl.cpp new file mode 100644 index 00000000000..9afc6a69dc4 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl.cpp @@ -0,0 +1,418 @@ +// $Id$ +#include "Plan_Launcher_Impl.h" +#include "orbsvcs/CosNamingC.h" +#include "Config_Handlers/XML_File_Intf.h" +#include "Config_Handlers/DnC_Dump.h" + +namespace CIAO +{ + namespace Plan_Launcher + { + // @todo make this a private method + static CORBA::Object_ptr + fetch_reference_naming (CORBA::ORB_ptr orb) + { + CORBA::Object_var tmp = + orb->resolve_initial_references ("NameService"); + + CosNaming::NamingContext_var pns = + CosNaming::NamingContext::_narrow (tmp.in ()); + + if (CORBA::is_nil (pns.in ())) + { + return CORBA::Object::_nil (); + } + + CosNaming::Name name (1); + name.length (1); + + name[0].id = CORBA::string_dup ("ExecutionManager"); + + return pns->resolve (name); + } + + Plan_Launcher_i::Plan_Launcher_i () + : em_ (), pg_ () + { + } + + bool + Plan_Launcher_i::init (const char *em_ior, + CORBA::ORB_ptr orb, + bool use_repoman, + bool rm_use_naming, + const char *rm_name) + { + CORBA::Object_var obj; + + // EM + if (em_ior == 0) + { + obj = fetch_reference_naming (orb); + } + else + { + obj = orb->string_to_object (em_ior); + } + + this->em_ = ::CIAO::ExecutionManagerDaemon::_narrow (obj.in ()); + + if (CORBA::is_nil (this->em_.in ())) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) CIAO_PlanLauncher: nil Execution" + " Manager reference, narrow failed\n")); + return false; + } + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) CIAO_PlanLauncher: Obtained Execution" + " Manager ref \n")); + } + + if (use_repoman) + { + return pg_.init (orb, rm_use_naming, rm_name); + } + else + { + return true; + } + } + + + const char * + Plan_Launcher_i::launch_plan (const char *deployment_plan_uri, + const char *package_uri, + bool use_package_name, + bool use_repoman) + ACE_THROW_SPEC ((Plan_Launcher_i::Deployment_Failure)) + { + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, "Parsing plan...\n")); + } + + CIAO::Config_Handlers::XML_File_Intf intf (deployment_plan_uri); + + ::Deployment::DeploymentPlan_var plan = + intf.get_plan (); + + // Use the package name(s) or type(s) to modify the location of all the + // artifacts in DeploymentPlan. + if (use_repoman) + { + // @todo check return value + pg_.generate_plan (plan, package_uri, use_package_name); + } + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, "Parsing complete....\n")); + } + + return this->launch_plan (plan.in ()); + } + + const char * + Plan_Launcher_i::launch_plan (const ::Deployment::DeploymentPlan &plan) + ACE_THROW_SPEC ((Plan_Launcher_i::Deployment_Failure)) + { + try + { + if (CORBA::is_nil (this->em_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("CIAO::Plan_Launcher_i: ") + ACE_TEXT ("launch_plan called witn an uninitialized EM.\n"))); + return 0; + } + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("CIAO::Plan_Launcher_i: " ) + ACE_TEXT ("about to call this->em_->preparePlan\n"))); + } + + ::Deployment::DomainApplicationManager_var dam (this->em_->preparePlan (plan, 1)); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("CIAO::Plan_Launcher_i: " ) + ACE_TEXT ("after to call this->em_->preparePlan\n"))); + } + + if (CORBA::is_nil (dam.in ())) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) CIAO_PlanLauncher:preparePlan call failed: " + "nil DomainApplicationManager reference\n")); + return 0; + } + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO_PlanLauncher: Obtained DAM ref \n")); + } + + ::Deployment::Properties_var properties; + ACE_NEW_RETURN (properties, + Deployment::Properties, + 0); + + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO_PlanLauncher: start Launch application...\n")); + } + + // Dont not start the Application immediately since it violates + // the semantics of component activation sequence + int start = 0; + + dam->startLaunch (properties.in (), 0); + + if (CIAO::debug_level ()) + ACE_DEBUG ((LM_DEBUG, "[success]\n")); + + // Call finish Launch to complete the connections + if (CIAO::debug_level ()) + ACE_DEBUG ((LM_DEBUG, + "CIAO_PlanLauncher: finish Launch application...\n")); + dam->finishLaunch (start, false); // is_ReDAC by default is <false> + + if (CIAO::debug_level ()) + ACE_DEBUG ((LM_DEBUG, "[success]\n")); + + // Call start to activate components + if (CIAO::debug_level ()) + ACE_DEBUG ((LM_DEBUG, + "CIAO_PlanLauncher: start activating components...\n")); + dam->start (); + + if (CIAO::debug_level ()) + ACE_DEBUG ((LM_DEBUG, "[success]\n")); + + if (CIAO::debug_level ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("CIAO_PlanLauncher: ") + ACE_TEXT ("Application Deployed successfully\n"))); + + map_.bind_dam_reference (plan.UUID.in (), + Deployment::DomainApplicationManager::_duplicate (dam.in ())); + } + catch (const Deployment::ResourceNotAvailable& ex) + { + ACE_ERROR ((LM_ERROR, + "EXCEPTION: ResourceNotAvaiable exception caught: %s,\n" + "Type: %s\n" + "Property: %s\n" + "Element: %s\n" + "Resource: %s\n", + ex.name.in (), + ex.resourceType.in (), + ex.propertyName.in (), + ex.elementName.in (), + ex.resourceName.in ())); + throw Deployment_Failure (""); + } + catch (const Deployment::StartError& ex) + { + ACE_ERROR ((LM_ERROR, + "EXCEPTION: StartError exception caught: %s, %s\n", + ex.name.in (), + ex.reason.in ())); + throw Deployment_Failure (""); + } + catch (const Deployment::InvalidProperty& ex) + { + ACE_ERROR ((LM_ERROR, + "EXCEPTION: InvalidProperty exception caught: %s, %s\n", + ex.name.in (), + ex.reason.in ())); + throw Deployment_Failure (""); + } + catch (const Deployment::InvalidConnection& ex) + { + ACE_ERROR ((LM_ERROR, + "EXCEPTION: InvalidConnection exception caught: %s, %s\n", + ex.name.in (), + ex.reason.in ())); + throw Deployment_Failure (""); + } + catch (const CORBA::Exception& ex) + { + ACE_ERROR ((LM_ERROR, + "CORBA EXCEPTION: %s\n", + ex._info().fast_rep())); + throw Deployment_Failure (""); + } + catch (...) + { + ACE_ERROR ((LM_ERROR, + "EXCEPTION: non-CORBA exception\n")); + throw Deployment_Failure (""); + } + + return CORBA::string_dup (plan.UUID.in ()); + } + + ::Deployment::DomainApplicationManager_ptr + Plan_Launcher_i::get_dam (const char *uuid) + { + if (!this->map_.is_plan_available (uuid)) + { + // Note: we could do an exhaustive (and expensive!) search of the DAMS + // on our EM at this point, if we wanted. In most cases, though, this + // would not produce a different result. + return Deployment::DomainApplicationManager::_nil (); + } + return this->map_.fetch_dam_reference (uuid); + } + + bool + Plan_Launcher_i::teardown_plan (const char *uuid) + { + // Since people could always run another instance of the Plan_Launcher + // executable to tear down a plan, so we could NOT rely on the local + // DAM_Map to fetch DAM obj reference. Instead, we make a remote call + // on ExecutionManager to fetch it. + try + { + ::Deployment::DomainApplicationManager_var dapp_mgr = + this->em_->getManager (uuid); + + if (!::CORBA::is_nil (dapp_mgr.in ())) + { + dapp_mgr->destroyApplication (); + + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, "[success]\n")); + } + + // Note that we should ask the DAM to tell EM whether the DAM should + // be destroyed + this->destroy_dam_by_plan (uuid); + } + } + catch (const CORBA::Exception&) + { + // @todo the destroy_dam_by_plan could give a stoperror exception + // we should handle + ACE_ERROR ((LM_ERROR, "Unable to find DomainApplicationManager " + "for plan with uuid: %s\n", uuid)); + return false; + } + + return true; + } + + bool + Plan_Launcher_i::teardown_plan (::Deployment::DomainApplicationManager_ptr dam) + { + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO_PlanLauncher: destroy the application.....\n")); + } + + dam->destroyApplication (); + + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, "[success]\n")); + } + + this->destroy_dam (dam); + + return true; + } + + void + Plan_Launcher_i::destroy_dam (::Deployment::DomainApplicationManager_ptr dam) + { + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO_PlanLauncher: destroy the manager.....\n")); + } + + this->em_->destroyManager (dam); + + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, "[success]\n")); + } + } + + void + Plan_Launcher_i::destroy_dam_by_plan (const char* plan_uuid) + { + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO_PlanLauncher: destroy the manager.....\n")); + } + + this->em_->destroyManagerByPlan (plan_uuid); + + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, "[success]\n")); + } + } + + const char * + Plan_Launcher_i::re_launch_plan (const char *deployment_plan_uri, + const char *package_uri, + bool use_package_name, + bool use_repoman) + ACE_THROW_SPEC ((Plan_Launcher_i::Deployment_Failure)) + { + CIAO::Config_Handlers::XML_File_Intf intf (deployment_plan_uri); + + ::Deployment::DeploymentPlan_var plan = + intf.get_plan (); + + // Use the package name(s) or type(s) to modify the location of all the + // artifacts in DeploymentPlan. + if (use_repoman) + { + // @todo use return value + pg_.generate_plan (plan, package_uri, use_package_name); + } + + return this->re_launch_plan (plan.in ()); + } + + const char * + Plan_Launcher_i::re_launch_plan (const ::Deployment::DeploymentPlan &plan) + ACE_THROW_SPEC ((Plan_Launcher_i::Deployment_Failure)) + { + + if (CORBA::is_nil (this->em_.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("CIAO::Plan_Launcher_i: ") + ACE_TEXT ("re_launch_plan called witn an uninitialized EM.\n"))); + return 0; + } + + this->em_->perform_redeployment (plan); + + if (CIAO::debug_level ()) + { + ACE_DEBUG ((LM_DEBUG, + "CIAO_PlanLauncher: new plan redeployed ...\n")); + } + + return CORBA::string_dup (plan.UUID.in ()); + } + } +} diff --git a/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl.h b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl.h new file mode 100644 index 00000000000..2212c00333f --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl.h @@ -0,0 +1,101 @@ +/** + * $Id$ + * @file Plan_Launcher_Impl.h + * @author Will Otte <wotte@dre.vanderbilt.edu> + * + * Contains the Plan_Launcher_i class, which can be used by + * applications to launch component assemblies. + */ +#ifndef PLAN_LAUNCHER_IMPL_H +#define PLAN_LAUNCHER_IMPL_H + +#include "Plan_Launcher_Impl_Export.h" +#include "ciao/CIAO_common.h" +#include "DAnCE/ExecutionManager/DAM_Map.h" +#include "DAnCE/Interfaces/ExecutionManagerDaemonC.h" +#include "DAnCE/Plan_Generator/Plan_Generator_Impl.h" + +namespace CIAO +{ + namespace Plan_Launcher + { + /** + * @class Plan_Launcher_i + * @brief This class launches and manages deployment plans. + */ + class Plan_Launcher_Impl_Export Plan_Launcher_i + { + public: + class Deployment_Failure { + public: + Deployment_Failure (const ACE_CString &error) + : error_ (error) + { + } + + ACE_CString error_; + }; + + Plan_Launcher_i (); + + + bool init (const char *em_ior, + CORBA::ORB_ptr orb, + bool use_repoman = false, + bool rm_use_naming = false, + const char *rm_name = 0); + + /** + * @brief Launch a plan, given a deployment plan URI + * @param deployment_plan_uri A uri that points ot a valid deployment plan + * @returns a string containing the UUID of the plan. Null indicates failure. + */ + const char * launch_plan (const char *deployment_plan_uri, + const char *package_uri = 0, + bool use_package_name = true, + bool use_repoman = false) + ACE_THROW_SPEC ((Deployment_Failure)); + + const char * re_launch_plan (const char *deployment_plan_uri, + const char *package_uri = 0, + bool use_package_name = true, + bool use_repoman = false) + ACE_THROW_SPEC ((Deployment_Failure)); + + /** + * @brief Launch a plan, given an IDL deployment plan + * @param plan A valid IDL deployment plan + * @returns a string containing the UUID of the plan. Null indicates failure. + */ + const char * launch_plan (const ::Deployment::DeploymentPlan &plan) + ACE_THROW_SPEC ((Deployment_Failure)); + + const char * re_launch_plan (const ::Deployment::DeploymentPlan &plan) + ACE_THROW_SPEC ((Deployment_Failure)); + + /// Returns the DAM associated with a given plan URI + ::Deployment::DomainApplicationManager_ptr get_dam (const char *uuid); + + /// Tears down a plan given the UUID + bool teardown_plan (const char *uuid); + + bool teardown_plan (::Deployment::DomainApplicationManager_ptr dam); + + void destroy_dam (::Deployment::DomainApplicationManager_ptr dam); + + void destroy_dam_by_plan (const char * plan_uuid); + + private: + ::CIAO::ExecutionManagerDaemon_var em_; + + /// Local map for DAMs, to save expensive UUID lookups. + Execution_Manager::DAM_Map map_; + + CIAO::Plan_Generator::Plan_Generator_i pg_; + }; + + } +} + + +#endif /* PLAN_LAUNCHER_IMPL_H */ diff --git a/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl_Export.h b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl_Export.h new file mode 100644 index 00000000000..1c85d1b98c9 --- /dev/null +++ b/modules/CIAO/DAnCE/Plan_Launcher/Plan_Launcher_Impl_Export.h @@ -0,0 +1,58 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl -s Config_Handlers +// ------------------------------ +#ifndef PLAN_LAUNCHER_IMPL_EXPORT_H +#define PLAN_LAUNCHER_IMPL_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (PLAN_LAUNCHER_IMPL_HAS_DLL) +# define PLAN_LAUNCHER_IMPL_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && PLAN_LAUNCHER_IMPL_HAS_DLL */ + +#if !defined (PLAN_LAUNCHER_IMPL_HAS_DLL) +# define PLAN_LAUNCHER_IMPL_HAS_DLL 1 +#endif /* ! PLAN_LAUNCHER_IMPL_HAS_DLL */ + +#if defined (PLAN_LAUNCHER_IMPL_HAS_DLL) && (PLAN_LAUNCHER_IMPL_HAS_DLL == 1) +# if defined (PLAN_LAUNCHER_IMPL_BUILD_DLL) +# define Plan_Launcher_Impl_Export ACE_Proper_Export_Flag +# define PLAN_LAUNCHER_IMPL_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define PLAN_LAUNCHER_IMPL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* PLAN_LAUNCHER_IMPL_BUILD_DLL */ +# define Plan_Launcher_Impl_Export ACE_Proper_Import_Flag +# define PLAN_LAUNCHER_IMPL_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define PLAN_LAUNCHER_IMPL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* PLAN_LAUNCHER_IMPL_BUILD_DLL */ +#else /* PLAN_LAUNCHER_IMPL_HAS_DLL == 1 */ +# define Plan_Launcher_Impl_Export +# define PLAN_LAUNCHER_IMPL_SINGLETON_DECLARATION(T) +# define PLAN_LAUNCHER_IMPL_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* PLAN_LAUNCHER_IMPL_HAS_DLL == 1 */ + +// Set PLAN_LAUNCHER_IMPL_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (PLAN_LAUNCHER_IMPL_NTRACE) +# if (ACE_NTRACE == 1) +# define PLAN_LAUNCHER_IMPL_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define PLAN_LAUNCHER_IMPL_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !PLAN_LAUNCHER_IMPL_NTRACE */ + +#if (PLAN_LAUNCHER_IMPL_NTRACE == 1) +# define PLAN_LAUNCHER_IMPL_TRACE(X) +#else /* (PLAN_LAUNCHER_IMPL_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define PLAN_LAUNCHER_IMPL_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (PLAN_LAUNCHER_IMPL_NTRACE == 1) */ + +#endif /* PLAN_LAUNCHER_IMPL_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/RepositoryManager/Options.cpp b/modules/CIAO/DAnCE/RepositoryManager/Options.cpp new file mode 100644 index 00000000000..a9fd5a67d3d --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/Options.cpp @@ -0,0 +1,147 @@ +// $Id$ + +// Options.cpp,v Stoyan + +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "Options.h" + + +bool +Options::parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("ov:n:l:u:t:icfdsTNa")); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'o': + this->write_to_ior_ = true; + this->register_with_ns_ = false; + break; + case 'v': + this->write_to_ior_ = false; + this->register_with_ns_ = true; + this->repoman_name_ = get_opt.opt_arg (); + break; + case 'i': + this->install_ = true; + break; + case 'c': + this->create_ = true; + break; + case 'd': + this->delete_ = true; + break; + case 'f': + this->find_ = true; + break; + case 's': + this->shutdown_ = true; + break; + case 'n': + this->name_ = get_opt.opt_arg (); + break; + case 'l': + this->path_ = get_opt.opt_arg (); + break; + case 'u': + this->uuid_ = get_opt.opt_arg (); + break; + case 'N': + this->all_names_ = true; + break; + case 'T': + this->all_types_ = true; + break; + case 't': + this->names_by_type_ = true; + this->type_ = get_opt.opt_arg (); + break; + // Usage fallthrough. + default: + this->usage (); + return false; + } + + if ((this->name_ == "") + && (this->shutdown_ == false) + && (this->uuid_ == "") + && (this->all_names_ == false) + && (this->all_types_ == false) + && (this->names_by_type_ == false)) + { + this->usage (); + return false; + } + else if (this->name_ != "") + { + if (!(this->install_ || this->create_ || this->find_ || this->delete_)) + { + this->usage (); + return false; + } + else if (this->install_ && this->path_ == "") + { + this->usage (); + return false; + } + else if (this->create_ && this->path_ == "") + { + this->usage (); + return false; + } + } + else if (this->uuid_ != "") + { + if (!this->find_) + { + this->usage (); + return false; + } + } + + return true; +} + +/// @todo Exit is not nice, return -1 so that the caller can do something and +/// we don't exit abruptly +void Options::usage (void) +{ + ACE_DEBUG ((LM_INFO, "OPTIONS: \n\ + -o <using ior file> \n\ + -v <: name of naming service> \n\ + -s <shutdown> \n\ + -n <:name> \n\ + [-i <install> -l <:path>] \n\ + [-c <create> -l <:path>] \n\ + [-d <delete>] \n\ + [-f <find>] \n\ + -u <:uuid> \n\ + [-f <find>] \n\ + -a <names by type> \n\ + [-t <:type>] \n\ + -N <all names> \n\ + -T <all types> \n")); +} + +Options::Options (void) + : name_ (""), + uuid_ (""), + type_ (""), + path_ (""), + delete_ (false), + install_ (false), + create_ (false), + find_ (false), + all_names_ (false), + all_types_ (false), + names_by_type_ (false), + shutdown_ (false), + register_with_ns_ (false), + write_to_ior_ (true), + repoman_name_ ("") +{ +} diff --git a/modules/CIAO/DAnCE/RepositoryManager/Options.h b/modules/CIAO/DAnCE/RepositoryManager/Options.h new file mode 100644 index 00000000000..845e339cedd --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/Options.h @@ -0,0 +1,93 @@ +// $Id$ + +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Options.h + * + * $Id$ + * + * TheOptions is an Options class wrapped into an ACE_Singleton + * with Null_Mutex because the client is single-threaded. + * + * + * @author Stoyan Paunov + */ +//============================================================================= + + +#ifndef RM_OPTIONS_H +#define RM_OPTIONS_H + +#include "ace/Get_Opt.h" +#include "ace/SString.h" //for ACE_CString +#include "ace/Singleton.h" //for ACE_Singleton +#include "ace/Null_Mutex.h" //for ACE_Null_Mutex + +//forward declaration +class Options; + +typedef ACE_Singleton <Options, ACE_Null_Mutex> TheOptions; + +class Options +{ +public: + + ///constructor + Options (void); + + /// parses commandline arguments + bool parse_args (int argc, ACE_TCHAR *argv[]); + + /// Name of package + ACE_CString name_; + + /// Name of package + ACE_CString uuid_; + + /// Type of package + ACE_CString type_; + + /// specifies the local path for install + ACE_CString path_; + + /// delete the name_ + bool delete_; + + /// installs the name_ + bool install_; + + /// creates the name_ + bool create_; + + /// finds the name_ + bool find_; + + /// get all Names + bool all_names_; + + /// get all types + bool all_types_; + + /// find all names by type + bool names_by_type_; + + /// shutdown the RepositoryManagerDemon + bool shutdown_; + + // use naming service + bool register_with_ns_; + + // use ior file + bool write_to_ior_; + + // Name of RepoMan + ACE_CString repoman_name_; + +protected: + //usage function + void usage (void); +}; + +#endif /* RM_OPTIONS_H */ diff --git a/modules/CIAO/DAnCE/RepositoryManager/PC_Updater.cpp b/modules/CIAO/DAnCE/RepositoryManager/PC_Updater.cpp new file mode 100644 index 00000000000..d2ce75e8666 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/PC_Updater.cpp @@ -0,0 +1,256 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ciao/Deployment_DataC.h" +#include "PC_Updater.h" +#include "PC_Updater_T.h" +#include "ace/Containers_T.h" //for ACE_Double_Linked_List + +namespace +{ + const size_t TEMP_LEN = 1024; +} + +using namespace PC_Updater_T; + + + //PATH of glory/gory to update the locations of the IADs + // + //PackageConfiguration something; + //ComponentPackageDescriptions basePackage; + //PackagedComponentImplementations implementation; + //ComponentImplementationDescription referencedImplementation; + // + //MONOLITHIC Component: + //MonolithicImplementationDescriptions monolithicImpl; + //NamedImplementationArtifacts primaryArtifact; + //ImplementationArtifactDescription referencedArtifact; + //::CORBA::StringSeq location; + // + //ASSEMBLY-BASED Component + //ComponentAssemblyDescriptions assemblyImpl; + //SubcomponentInstantiationDescriptions instance; + //ComponentPackageDescriptions package; + //... + + + /* + * PC_Updater Constructors + */ + +PC_Updater::PC_Updater (const char* server_path, const char* package) +: server_path_ (server_path), + file_list_ (), + package_ (package), + success_ (true) +{ +} + + +PC_Updater::PC_Updater (ACE_CString& server_path, ACE_CString& package) +: server_path_ (server_path), + file_list_ (), + package_ (package), + success_ (true) +{ +} + + /* + * PC_Updater - Destructor + */ + +PC_Updater::~PC_Updater () +{ + this->clear_list (); +} + + +void PC_Updater::clear_list () +{ + while (!this->file_list_.is_empty ()) + { + ZIP_File_Info* inf = this->file_list_.delete_head (); + + //deallocate the head of the filename list + delete inf; + } +} + + + /* + * PC_Updater - Object update methods + */ + + + // PackageConfiguration + + bool PC_Updater::update (::Deployment::PackageConfiguration &pc) + { + //get the list of files in the package and figure out the names of all necessary files + if (!ZIP_Wrapper::file_list_info (const_cast <char*> (this->package_.c_str ()), this->file_list_)) + return false; + + update_sequence (pc.basePackage, this); + + return this->success_; + } + + + // ComponentInterfaceDescription + + void PC_Updater::update (::Deployment::ComponentInterfaceDescription &) + { + } + + // Requirement + + void PC_Updater::update (::Deployment::Requirement &) + { + } + + + // ComponentExternalPortEndpoint + + void PC_Updater::update (::Deployment::ComponentExternalPortEndpoint &) + { + } + + + + // ImplementationDependency + + void PC_Updater::update (Deployment::ImplementationDependency &) + { + } + + // ComponentPackageReference + + void PC_Updater::update (::Deployment::ComponentPackageReference &) + { + } + + // SubcomponentInstantiationDescription + + void PC_Updater::update (::Deployment::SubcomponentInstantiationDescription &sid) + { + update_sequence (sid.basePackage, this); + } + + // SubcomponentPortEndpoint + + void PC_Updater::update (::Deployment::SubcomponentPortEndpoint& ) + { + } + + // AssemblyConnectionDescription + + void PC_Updater::update (::Deployment::AssemblyConnectionDescription &) + { + } + + + // AssemblyPropertyMapping + + void + PC_Updater::update (::Deployment::AssemblyPropertyMapping &) + { + } + + // ComponentAssemblyDescription + + void PC_Updater::update (::Deployment::ComponentAssemblyDescription& cad) + { + update_sequence (cad.instance, this); + } + + // ImplementationArtifactDescription + + void PC_Updater::update (::Deployment::ImplementationArtifactDescription &iad) + { + const char* location = CORBA::string_dup (iad.location[0]); + + //create an iterator + ACE_Double_Linked_List_Iterator<ZIP_File_Info> iter (this->file_list_); + + //find the correct path and return + while (!iter.done ()) + { + const char* full_path = iter.next ()->name_.c_str (); + //weird. Need to call next to get current ?!?! + + //is it an implementation artifact? + const char* name = ACE_OS::strstr (full_path, "implementations/"); + if (name) + { + //now check if the name matches + name = ACE_OS::strstr (full_path, iad.location[0]); + + if (name) + { + ACE_CString loc (this->server_path_); + loc += "/implementations/"; + loc += location; + + iad.location[0] = CORBA::string_dup (loc.c_str ()); + + //cout << "Location after update: " << iad.location[0] << endl << endl; + return; + } + } + iter++; + } + + ACE_ERROR ((LM_ERROR, + "[PC_Updater::update] Unable to update: %s!\n", + location)); + + this->success_ = false; + } + + // NamedImplementationArtifact + + void PC_Updater::update (::Deployment::NamedImplementationArtifact &nia) + { + update (nia.referencedArtifact); + } + + // ImplementationRequirement + void PC_Updater::update (::Deployment::ImplementationRequirement &) + { + } + + // MonolithicImplementationDescription + void PC_Updater::update (::Deployment::MonolithicImplementationDescription &mid) + { + update_sequence (mid.primaryArtifact, this); + } + + // Capability + void PC_Updater::update (::Deployment::Capability &) + { + } + + // ComponentImplementationDescription + void PC_Updater::update (::Deployment::ComponentImplementationDescription &cid) + { + update_sequence (cid.assemblyImpl, this); + update_sequence (cid.monolithicImpl, this); + } + + // PackagedComponentImplementation + void PC_Updater::update (::Deployment::PackagedComponentImplementation &pci) + { + PC_Updater::update (pci.referencedImplementation); + } + + // ComponentPackageDescription + void PC_Updater::update (::Deployment::ComponentPackageDescription &comppkgdesc) + { + update_sequence (comppkgdesc.implementation, this); + } + + + // Property + void PC_Updater::update (Deployment::Property& ) + { + } diff --git a/modules/CIAO/DAnCE/RepositoryManager/PC_Updater.h b/modules/CIAO/DAnCE/RepositoryManager/PC_Updater.h new file mode 100644 index 00000000000..9c6d326f54d --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/PC_Updater.h @@ -0,0 +1,113 @@ + +/* -*- C++ -*- */ + +//======================================================================== +/** + * file PC_Updater.h + * + * $Id$ + * + * This class is used to update the location field of the implementation + * artifacts in the PackageConfiguration, so that they point to the + * physical libraries on the collocated HTTP server + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + */ +//======================================================================== + +#ifndef PC_UPDATER_H +#define PC_UPDATER_H +#include /**/ "ace/pre.h" + +#include "ciao/DeploymentC.h" +#include "ace/SString.h" //for the ACE_CString + +#include "ZIP_Wrapper.h" //Wrapper around zzip +#include "ace/Containers_T.h" //for ACE_Double_Linked_List +#include "ace/Malloc_Allocator.h" //for ACE_New_Allocator needed by the doubly link list + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class PC_Updater + * + * This class defines a set of overloaded methods used to update + * the contents of a PackageConfiguration. More specifically the class + * goes through the PackageConfiguration and updates the locations of the + * artifacts, wrt to their location on the HTTP server. + */ +class PC_Updater +{ +public: + + /// Constructors + + PC_Updater (const char* server_path, const char* package); + PC_Updater (ACE_CString& server_path, ACE_CString& package); + + ~PC_Updater (); + + /// A whole slew of overloaded routines for different IDL + /// data types part of the PackageConfiguration. + + bool update (::Deployment::PackageConfiguration &pc); + + void update (::Deployment::Property &property); + + void update (::Deployment::AssemblyConnectionDescription &acd); + + void update (::Deployment::AssemblyPropertyMapping &apm); + + void update (::Deployment::ComponentPackageDescription &comppkgdesc); + + void update (::Deployment::MonolithicImplementationDescription &mid); + + void update (::Deployment::PackagedComponentImplementation &pci); + + void update (::Deployment::SubcomponentPortEndpoint &spe); + + void update (::Deployment::Requirement &requirement); + + void update (::Deployment::ComponentExternalPortEndpoint &cepe); + + void update (::Deployment::ComponentPackageReference &cpr); + + void update (::Deployment::ComponentImplementationDescription &cid); + + void update (::Deployment::SubcomponentInstantiationDescription &sid); + + void update (::Deployment::NamedImplementationArtifact &named_implementation); + + void update (::Deployment::ComponentInterfaceDescription &cid); + + void update (::Deployment::Capability &capability); + + void update (::Deployment::ImplementationArtifactDescription &iad); + + void update (::Deployment::ImplementationRequirement &ir); + + void update (::Deployment::ImplementationDependency &id); + + void update (::Deployment::ComponentAssemblyDescription& cad); + +protected: + + void clear_list (); + +private: + + ACE_CString server_path_; + + /// create a doubly link list + //ACE_New_Allocator allocator_; + ACE_Double_Linked_List<ZIP_File_Info> file_list_; + + ACE_CString package_; + bool success_; +}; + +#include /**/ "ace/post.h" + +#endif /* PC_UPDATER_H */ diff --git a/modules/CIAO/DAnCE/RepositoryManager/PC_Updater_T.cpp b/modules/CIAO/DAnCE/RepositoryManager/PC_Updater_T.cpp new file mode 100644 index 00000000000..a5f5ec5fb2e --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/PC_Updater_T.cpp @@ -0,0 +1,20 @@ +// $Id$ +#ifndef PC_UPDATER_T_C +#define PC_UPDATER_T_C +#include "PC_Updater.h" +#include "PC_Updater_T.h" + +namespace PC_Updater_T +{ + /// Dumps a sequence + template <typename SEQUENCE> + void update_sequence (SEQUENCE &seq, PC_Updater* updater) + { + CORBA::ULong const size = seq.length (); + + for (CORBA::ULong i = 0; i < size; ++i) + updater->update (seq[i]); + } +} + +#endif /* PC_Updater_C */ diff --git a/modules/CIAO/DAnCE/RepositoryManager/PC_Updater_T.h b/modules/CIAO/DAnCE/RepositoryManager/PC_Updater_T.h new file mode 100644 index 00000000000..0696c685e2b --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/PC_Updater_T.h @@ -0,0 +1,40 @@ + +/* -*- C++ -*- */ + +//================================================================== +/** + * file PC_Updater_T.h + * + * $Id$ + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + */ +//===================================================================== + +#ifndef CIAO_CONFIG_HANDLERS_PC_UPDATER_T_H +#define CIAO_CONFIG_HANDLERS_PC_UPDATER_T_H +#include /**/ "ace/pre.h" + +#include "ace/config-lite.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace PC_Updater_T +{ + template <typename SEQUENCE> + static void update_sequence (SEQUENCE &seq); +} + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "PC_Updater_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("PC_Updater_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + + +#include /**/ "ace/post.h" +#endif /*CIAO_CONFIG_HANDLERS_PC_Updater_T_H*/ diff --git a/modules/CIAO/DAnCE/RepositoryManager/README b/modules/CIAO/DAnCE/RepositoryManager/README new file mode 100644 index 00000000000..322b00098ac --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/README @@ -0,0 +1,46 @@ +This is the README file for the Repository Manager (RM). + +Building RM: +In order to be able to compile the RM you need to have ZLIB lib because the RM +uses it to read the contents of CCM packages. In order to compile the RM +successfully you will need to do the following: +1.Download the binary version of ZLIB or build it yourself +3.Create an "include" and a "lib" subdirectory. Then copy the libraries files into + the "lib" subdirectory and copy zlib.h into the "include" subdirectory. +4.Set $ZLIB_ROOT to point to the directories where you placed the libraries and + the include files. +5.Turn on zzip and zlib in default.features for MPC. +6.MPC will handle the rest. + +If you want to get the component package through http server: +1.Be sure to set JAWS_DOCUMENT_ROOT to the installation path of the RepoMan, i.e., $CIAO_ROOT/DAnCE/RepositoryManager. +2.Start JAWS: $ACE_ROOT/apps/JAWS/server/main + +Start RM: +1.Using ior file: + RepositoryManagerDaemon -o +2.Using Naming Service: + RepositoryManagerDaemon -v [NameofRM] + +Using RMadmin: +1.Install component package: (use BasicSP for example) + Be sure you have BasicSP.cpk in the $CIAO_ROOT/DAnCE/RepositoryManager/packages + > RMadmin -o -n BasicSP -i -l packages/BasicSP.cpk + or + > RMadmin -o -n BasicSP -i -l http://127.0.0.1:5432/packages/BasicSP.cpk (If the JAWS is started) + This will create the BasicSP directory, BasicSP.cpk file and BasicSP.epc file in the + $CIAO_ROOT/DAnCE/RepositoryManager/RepositoryManager/ +2.Delete component package: (use BasicSP for example) + > RMadmin -o -n BasicSP -d +3.Find component package by its name: (use BasicSP for example) + > RMadmin -o -n BasicSP -f +4.Stop RM: + > RMadmin -o -s + This will create the RM_record file in the $CIAO_ROOT/DAnCE/RepositoryManager/RepositoryManager/ which record the + names and UUIDs of the installed component packages. + + + + + + diff --git a/modules/CIAO/DAnCE/RepositoryManager/RM_Helper.cpp b/modules/CIAO/DAnCE/RepositoryManager/RM_Helper.cpp new file mode 100644 index 00000000000..cd4b92669d0 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/RM_Helper.cpp @@ -0,0 +1,265 @@ +// $Id$ + +#include "RM_Helper.h" +#include "ace/Auto_Ptr.h" //for Auto_Ptr +#include "ace/OS_NS_fcntl.h" //for open +#include "ace/OS_NS_unistd.h" //for close +#include "ace/OS_NS_sys_stat.h" //for filesize and mkdir +#include "ace/OS_NS_string.h" + + +void +RM_Helper::pc_to_cdr (const Deployment::PackageConfiguration& pc, TAO_OutputCDR& cdr) +{ + cdr << pc; +} + + +void +RM_Helper::cdr_to_pc (Deployment::PackageConfiguration& pc, TAO_InputCDR& cdr) +{ + cdr >> pc; +} + + +bool +RM_Helper::externalize (const Deployment::PackageConfiguration& pc, const char* path) +{ + size_t bufsiz = 0; + TAO_OutputCDR out (bufsiz); + + RM_Helper::pc_to_cdr (pc, out); + + const ACE_Message_Block* mb = out.begin (); + + return write_pc_to_disk (path, *(const_cast<ACE_Message_Block*> (mb))); +} + + +bool +RM_Helper::reincarnate (Deployment::PackageConfiguration& pc, const char* path) +{ + size_t length = 0; + ACE_Auto_Ptr<ACE_Message_Block> mb (read_pc_from_disk (path, length)); + + if (!mb.get ()) + return false; + + TAO_InputCDR in (mb.get ()); + + RM_Helper::cdr_to_pc (pc, in); + + return true; +} + + +/// This function attempts to copy the file from a specified location +/// to another specified location on the hard disk. +bool +RM_Helper::copy_from_disk_to_disk (const char* from_path, const char* to_path) +{ + if (ACE_OS::strcmp (from_path, to_path) == 0) + return true; + + // Open the files + ACE_HANDLE from_handle = ACE_OS::open (from_path, O_RDONLY); + if (from_handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::copy_from_disk_to_disk] file open error")), + 0); + + ACE_stat file_info; + ACE_OS::fstat (from_handle, &file_info); + ACE_UINT64 file_length = file_info.st_size; + + ACE_HANDLE to_handle = ACE_OS::open (to_path, O_CREAT | O_TRUNC | O_WRONLY); + if (to_handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::copy_from_disk_to_disk] file creation error")), + 0); + + + // Read the contents of the file into the buffer and write the data to another file + ACE_Message_Block *mb = 0; + size_t length; + size_t number = 0; + bool last = false; + + while (true) + { + if ((file_length - BUFSIZ*number) > BUFSIZ) + length = BUFSIZ; + else + { + length = static_cast<size_t> (file_length - BUFSIZ*number); + last = true; + } + + mb = new ACE_Message_Block (length); + + if (ACE_OS::read_n (from_handle, mb->wr_ptr (), length) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::copy_from_disk_to_disk] file read error")), + 0); + + ++number; + + mb->length (length); + + for (ACE_Message_Block *curr = mb; curr != 0; curr = curr->cont ()) + if (ACE_OS::write_n (to_handle, curr->rd_ptr (), curr->length ()) == -1) + { + mb->release (); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::copy_from_disk_to_disk] file write error")), + 0); + } + + mb->release (); + + if (last) + break; + } + + // Close the files + ACE_OS::close (from_handle); + ACE_OS::close (to_handle); + + return true; +} + + +/// This function attempts to write a sequence of bytes from an +/// ACE_Message_Block to a specified location. A 0 is returned +/// in the case of an error and a 1 upon success +bool RM_Helper::write_to_disk ( + const char* full_path, + ACE_Message_Block& mb, + bool replace + ) +{ + ACE_stat stat; + + if (ACE_OS::stat(full_path, &stat) != -1 && !replace) + return false; + + // Open a file handle to the local filesystem + ACE_HANDLE handle = ACE_OS::open (full_path, O_CREAT | O_TRUNC | O_WRONLY); + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::write_to_disk] file creation error")), + false); + + // Write the data to the file + for (ACE_Message_Block * curr = &mb; curr != 0; curr = curr->cont ()) + if (ACE_OS::write_n (handle, curr->rd_ptr(), curr->length()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("write error")), + false); + + // Close the file handle + ACE_OS::close (handle); + + return true; +} + + +/// This function attempts to write a sequence of bytes from an +/// ACE_Message_Block to a specified location. A 0 is returned +/// in the case of an error and a 1 upon success +/// +/// @note This function write the contents in a way that preserves the +/// structure of the ACE_Message_Block. It is relevant for +/// PackageConfigurations ONLY +bool RM_Helper::write_pc_to_disk ( + const char* full_path, + ACE_Message_Block& mb, + bool replace + ) +{ + ACE_stat stat; + + if (ACE_OS::stat(full_path, &stat) != -1 && !replace) + return false; + + // Open a file handle to the local filesystem + ACE_HANDLE const handle = ACE_OS::open (full_path, O_CREAT | O_TRUNC | O_WRONLY); + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::write_to_disk] file creation error")), + false); + + // write the data to the file + for (ACE_Message_Block * curr = &mb; curr != 0; curr = curr->cont ()) + if (ACE_OS::write_n (handle, curr->rd_ptr(), curr->length()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("write error")), + 0); + + // Close the file handle + ACE_OS::close (handle); + + return true; +} + + +/// Function to read the contents of a file from disk into an ACE_Message_Block +/// returns a pointer to an ACE_Message_Block and updates the lenght on success +/// 0 on failure +ACE_Message_Block* +RM_Helper::read_pc_from_disk ( + const char* full_path, + size_t &length + ) +{ + length = 0; + + // Open the file + ACE_HANDLE const handle = ACE_OS::open (full_path, O_RDONLY); + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::read_mb_from_disk] file open error")), + 0); + + ACE_stat file_info; + ACE_OS::fstat (handle, &file_info); + + // Get and check the length of the file + length = static_cast<size_t> (file_info.st_size); + + ACE_INT64 check = length; + if (check != file_info.st_size) + { + length = 0; + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::read_mb_from_disk] file length error")), + 0); + } + + // Read the contents of the file into the buffer + ACE_Message_Block* mb = 0; + ACE_NEW_RETURN (mb, ACE_Message_Block (length + 1), 0); + + if (ACE_OS::read_n (handle, mb->wr_ptr (), length) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[RM::read_mb_from_disk] file read error")), + 0); + + mb->length (length); + + // Close the file handle + ACE_OS::close (handle); + + return mb; +} diff --git a/modules/CIAO/DAnCE/RepositoryManager/RM_Helper.h b/modules/CIAO/DAnCE/RepositoryManager/RM_Helper.h new file mode 100644 index 00000000000..f76764e3b11 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/RM_Helper.h @@ -0,0 +1,81 @@ + +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file RM_Helper.h + * + * $Id$ + * + * This class aggregates a number of helper functions used by the + * CIAO RepositoryManager + * + * + * @author Stoyan Paunov + */ +//============================================================================= + +#ifndef RM_HELPER_H_ +#define RM_HELPER_H_ + + +#include "ciao/Deployment_Packaging_DataC.h" +#include "tao/CDR.h" +#include "ace/Message_Block.h" + + +class RM_Helper +{ +public: + + static void pc_to_cdr (const Deployment::PackageConfiguration& pc, TAO_OutputCDR& cdr); + + static void cdr_to_pc (Deployment::PackageConfiguration& pc, TAO_InputCDR& cdr); + + static bool externalize (const Deployment::PackageConfiguration& pc, const char* path); + + static bool reincarnate (Deployment::PackageConfiguration& pc, const char* path); + + /** + * Function that copies the file from a specified location to another + * specified location on the hard disk. + * @retval true on success + * @retval false on error + */ + static bool copy_from_disk_to_disk (const char* from_path, const char* to_path); + + /** + * Function that writes out a file to a specified location on the hard disk + * @retval true on success + * @retval false on already exists and replace == false + * @retval false on error + */ + static bool write_to_disk (const char* full_path, + ACE_Message_Block& mb, + bool replace = true + ); + + /** + * Function that writes out a file to a specified location on the hard disk + * @retval true on success + * @retval false on already exists and replace == false + * @retval 0 on error + * @note This function is relevant for PackageConfigurations ONLY + */ + static bool write_pc_to_disk (const char* full_path, + ACE_Message_Block& mb, + bool replace = true); + + /** + * Function to read the contents of a file from disk into an + * ACE_Message_Block returns a pointer to an ACE_Message_Block and updates + * the lenght on success + * @retval 0 on failure + */ + + static ACE_Message_Block* read_pc_from_disk (const char* full_path, + size_t &length); + +}; + +#endif diff --git a/modules/CIAO/DAnCE/RepositoryManager/RMadmin.cpp b/modules/CIAO/DAnCE/RepositoryManager/RMadmin.cpp new file mode 100644 index 00000000000..f61a9f2a71e --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/RMadmin.cpp @@ -0,0 +1,249 @@ +/* -*- C++ -*- */ + +/*** + * file RMClient.cpp + * + * $Id$ + * + * A sample client to the RepositoryManager showcasing how to use it + * + * author Stoyan Paunov <spaunov@isis.vanderbilt.edu> + * Shanshan Jiang <shanshan.jiang@vanderbilt.edu> + **/ + +#include "RepositoryManagerDaemonC.h" +#include "Options.h" + +#include "ace/OS_NS_fcntl.h" //for open +#include "ace/OS_NS_unistd.h" //for close +#include "ace/OS_NS_sys_stat.h" //for filesize and fstat and mkdir +#include "ace/streams.h" + +#include "Config_Handlers/DnC_Dump.h" + +#include "RM_Helper.h" //to be able to externalize/internalize a PackageConfiguration +#include "tao/CDR.h" //for TAO CDR classes +#include "ace/Message_Block.h" //for ACE_Message_Block + +#include "Package_Handlers/PCD_Handler.h" + +#include "orbsvcs/CosNamingC.h" + + +//IOR file of the RM +static const char *ior = "file://RepositoryManagerDaemon.ior"; + +// Name service of the RM +static const char *RMname_service; + +/// main function that provides a sample interface for RM clients +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + try + { + // Initialize orb + CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, + ""); + + + Options* options = TheOptions::instance (); + if (!options->parse_args (argc, argv)) + return -1; + + CORBA::Object_var obj; + + if (options->write_to_ior_) + { + obj = orb->string_to_object (ior); + } + + else if (options->register_with_ns_) + { + if (options->repoman_name_ != "") + RMname_service = const_cast<char*> (options->repoman_name_.c_str ()); + + // 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 (RMname_service); + + // Resolve object from name + obj = naming_context->resolve (name); + } + + + CIAO::RepositoryManagerDaemon_var rm = + CIAO::RepositoryManagerDaemon::_narrow (obj.in ()); + + if (CORBA::is_nil (rm.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Unable to acquire RepositoryManagerDaemon's objref\n"), + -1); + } + + if (options->shutdown_) + { + rm->shutdown (); + } + else if (options->all_names_) + { + try + { + CORBA::StringSeq_var seq = rm->getAllNames (); + cout << "Known Names:\n"; + for (size_t i = 0; + i < seq->length (); + ++i) + cout << seq[i] << endl; + } + catch (CORBA::Exception & ex) + { + cout << "\nException caught!" << ex << "\n"; + return 0; + } + } + else if (options->all_types_) + { + try + { + CORBA::StringSeq_var seq = rm->getAllTypes (); + cout << "Known Component Interface Types:\n"; + for (size_t i = 0; + i < seq->length (); + ++i) + cout << seq[i] << endl; + } + catch (CORBA::Exception & ex) + { + cout << "\nException caught!" << ex << "\n"; + return 0; + } + } + else if (options->type_ != "" && options->names_by_type_) + { + try + { + CORBA::StringSeq_var seq = rm->findNamesByType (options->type_.c_str ()); + cout << "Known Component Interface Types:\n"; + for (size_t i = 0; + i < seq->length (); + ++i) + cout << seq[i] << endl; + } + catch (CORBA::Exception & ex) + { + cout << "\nException caught!" << ex << "\n"; + return 0; + } + } + else if (options->install_) + { + try + { + rm->installPackage (options->name_.c_str (), options->path_.c_str (), false); + } + catch (CORBA::Exception & ex) + { + cout << "\nException caught!" << ex << "\n"; + return 0; + } + + cout << "\nReassuring that the package in the repository ..." << endl; + try + { + Deployment::PackageConfiguration_var pc = rm->findPackageByName (options->name_.c_str ()); + cout << "The package was found!" << endl; + cout << "Label: " << pc->label << endl; + cout << "UUID: " << pc->UUID << endl; + } + catch (CORBA::Exception &) + { + cout << "\nError! Package not found!" << endl; + } + } + else if (options->create_) + { + try + { + // Change the working dir. + char cwd [1024]; + ACE_OS::getcwd (cwd, 1024); + ACE_CString descriptor_dir (cwd); + descriptor_dir += "/packageDescriptors/RACE/descriptors/"; + ACE_OS::chdir (descriptor_dir.c_str ()); + + Deployment::PackageConfiguration *pc = new Deployment::PackageConfiguration (); + + // Parse the PCD to make sure that there are no package errors. + try + { + CIAO::Config_Handlers::Packaging::PCD_Handler::package_config ("default.pcd", *pc); + } + catch (...) + { + ACE_ERROR (( + LM_ERROR, + "(%P|%t) [RM::retrieve_PC_from_descriptors] Error parsing the PCD\n")); + + throw Deployment::PackageError (); + } + + ACE_OS::chdir (cwd); + + rm->createPackage (options->name_.c_str (), *pc, options->path_.c_str (), false); + } + catch (CORBA::Exception & ex) + { + cout << "\nException caught!" << ex << "\n"; + return 0; + } + } + else if (options->delete_) + { + try + { + rm->deletePackage (options->name_.c_str ()); + cout << options->name_.c_str () << " deleted" << endl; + } + catch (CORBA::Exception & ex) + { + cout << "\nException: " << ex << endl; + } + + } + else if (options->find_) + { + if (options->name_ != "") + { + Deployment::PackageConfiguration_var pc = rm->findPackageByName (options->name_.c_str ()); + cout << "The package was found!" << endl; + //Deployment::DnC_Dump::dump (pc); + } + else + { + Deployment::PackageConfiguration_var pc = rm->findPackageByUUID (options->uuid_.c_str ()); + cout << "The package was found!" << endl; + //Deployment::DnC_Dump::dump (pc); + } + } + + orb->shutdown (1); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Unknown exception \n"); + return -1; + } + + return 0; +} diff --git a/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager.cpp b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager.cpp new file mode 100644 index 00000000000..10d67721cd0 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager.cpp @@ -0,0 +1,279 @@ + +/* -*- C++ -*- */ + +//====================================================================== +/** + * @file RepositoryManager.cpp + * + * $Id$ + * + * Description: + * Main driver program for the CIAO RepositoryManager + * Please run as follows: + * RepositoryManagerDaemon [int:nthreads] + * + * @author Stoyan Paunov + */ +//====================================================================== + +#include "RepositoryManager_Impl.h" +#include "ace/OS_NS_stdio.h" +#include "ace/streams.h" +#include "ace/Auto_Ptr.h" +#include "ace/Task.h" +#include "ace/Get_Opt.h" +#include "ace/SString.h" + +#include "orbsvcs/CosNamingC.h" + +namespace CIAO +{ + namespace RepositoryManager + { + /// Name of the file holding the IOR of the RM + const char * RMior = "RepositoryManagerDaemon.ior"; + + // Name of RepoMan + const char * repoman_name_ = "RepositoryManager"; + + //Name service of the RM + const char * RMname_service = "RepositoryManager"; + + /// Default number of worker threads to run in the multi-threaded RM + static unsigned int nthreads = 3; + static ACE_CString HTTPserver = "127.0.0.1:5432"; + + static bool register_with_ns_ = false; + static bool write_to_ior_ = true; + } +} + +// Forward declaration +bool parse_args (int argc, char *argv[]); + +/** + * @class Worker + * + * Class that implements the service routine of the worker threads + * of the repository manager + */ +class Worker : public ACE_Task_Base +{ +public: + /// ctor + Worker (CORBA::ORB_ptr orb); + + /// The thread entry point. + virtual int svc (void); + +private: + /// The orb + CORBA::ORB_var orb_; +}; + +bool +write_ior_file (CORBA::ORB_ptr orb, + CIAO::RepositoryManagerDaemon_ptr obj) +{ + CORBA::String_var ior = + orb->object_to_string (obj); + + FILE* RMior_file = + ACE_OS::fopen (CIAO::RepositoryManager::RMior, "w"); + + if (RMior_file) + { + ACE_OS::fprintf (RMior_file, + "%s", + ior.in ()); + ACE_OS::fclose (RMior_file); + } + else + { + return false; + } + + return true; +} + +bool +register_with_ns (CORBA::ORB_ptr orb, + CIAO::RepositoryManagerDaemon_ptr obj) +{ + if (CIAO::RepositoryManager::repoman_name_ != "") + CIAO::RepositoryManager::RMname_service = + CIAO::RepositoryManager::repoman_name_; + + // 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 (CIAO::RepositoryManager::RMname_service); + + // Register the servant with the Naming Service + naming_context->rebind (name, obj); + + return true; +} + +///Main function + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + try + { + //init the ORB + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + + if (!parse_args (argc, argv)) + return -1; + + // Get the root POA object + CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA"); + + // Downcast to POA type + PortableServer::POA_var root_poa = PortableServer::POA::_narrow (obj.in ()); + + //activate the POA manager + PortableServer::POAManager_var mgr = root_poa->the_POAManager (); + mgr->activate (); + + // Create a servant + CIAO_RepositoryManagerDaemon_i* repo = 0; + ACE_NEW_RETURN (repo, + CIAO_RepositoryManagerDaemon_i ( + orb.in (), + CIAO::RepositoryManager::HTTPserver.c_str (), + CIAO::RepositoryManager::repoman_name_), + 1); + + //transfer ownership to the POA + PortableServer::ServantBase_var owner_transfer(repo); + + //register and implicitly activate servant + CIAO::RepositoryManagerDaemon_var RepositoryManagerDaemon = repo->_this (); + + bool retval = false; + + if (CIAO::RepositoryManager::write_to_ior_) + { + retval = + write_ior_file (orb.in (), + RepositoryManagerDaemon.in ()); + } + else if (CIAO::RepositoryManager::register_with_ns_) + { + retval = + register_with_ns (orb.in (), + RepositoryManagerDaemon.in ()); + } + + if (!retval) + return -1; + + + Worker worker (orb.in ()); + if (worker.activate (THR_NEW_LWP | THR_JOINABLE, + CIAO::RepositoryManager::nthreads) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot activate worker threads\n"), + 1); + + worker.thr_mgr ()->wait (); + + ACE_DEBUG ((LM_DEBUG, "event loop finished\n")); + + // done + return 0; + + // todo shutdown orb + } + catch (CORBA::Exception &ex) { + cerr << "CORBA Exception: " << ex << endl; + + return 1; + } + + + return 0; +} + + +// **************************************************************** + +///Code to parse the arguments + + bool + parse_args (int argc, char *argv[]) + { + ACE_Get_Opt get_opts (argc, argv, "ov:s:n:"); + int c; + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + CIAO::RepositoryManager::write_to_ior_ = true; + CIAO::RepositoryManager::register_with_ns_ = false; + break; + case 'v': + CIAO::RepositoryManager::write_to_ior_ = false; + CIAO::RepositoryManager::register_with_ns_ = true; + CIAO::RepositoryManager::repoman_name_ = get_opts.opt_arg (); + break; + case 's': + CIAO::RepositoryManager::HTTPserver = get_opts.opt_arg (); + break; + case 'n': + CIAO::RepositoryManager::nthreads = ACE_OS::atoi (get_opts.opt_arg ()); + break; + case '?': // display help for use of the server. + ACE_DEBUG ((LM_INFO, + "usage: %s\n" + "-o <using ior file>\n" + "-v <name of naming service>\n" + "-s <IP:PORT for HTTP server>\n" + "-n <number of threads>\n", + argv [0])); + return false; + break; + default: + ; + } + + return true; + } + + + +// **************************************************************** + +///Constuctor for the worker class +Worker::Worker (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ +} + +///implementation of the service routine inherited from ACE::Task_Base + +int Worker::svc (void) +{ + try + { + this->orb_->run (); + } + catch (const CORBA::Exception& ex) + { + } + return 0; +} + + diff --git a/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager.mpc b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager.mpc new file mode 100644 index 00000000000..b20b77e2d6c --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager.mpc @@ -0,0 +1,53 @@ +// -*- MPC -*- +// $Id$ + +//RepositoryManager project: implementation of a repository manager +//compleint with the D&C spec + +project (RepositoryManager) : ciao_server_dnc, ciao_config_handlers, zlib { + + includes += $(CIAO_ROOT)/tools/Config_Handlers $(ACE_ROOT)/contrib/minizip + //to circumvent an improper include resolution + //in the Package_Handlers/PC_Intf.h + exename = RepositoryManagerDaemon + requires += zlib + after += minizip + libs += Package_Config_Handlers minizip + + IDL_Files { + RepositoryManagerDaemon.idl + } + + Source_Files { + RepositoryManagerDaemonC.cpp + RepositoryManagerDaemonS.cpp + ZIP_Wrapper.cpp + RepositoryManager.cpp + RepositoryManager_Impl.cpp + RM_Helper.cpp + URL_Parser.cpp + PC_Updater_T.cpp + PC_Updater.cpp + } + +} + + + +// RMadmin project: a sample client for the RM. + +project (RMAdmin) : ciao_servant_dnc, ciao_config_handlers { + exename = RMadmin + after += RepositoryManager + + IDL_Files { + RepositoryManagerDaemon.idl + } + + Source_Files { + RMadmin.cpp + RepositoryManagerDaemonC.cpp + Options.cpp + RM_Helper.cpp + } +} diff --git a/modules/CIAO/DAnCE/RepositoryManager/RepositoryManagerDaemon.idl b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManagerDaemon.idl new file mode 100644 index 00000000000..7f28e7d5683 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManagerDaemon.idl @@ -0,0 +1,13 @@ +// $Id$ + +#include "ciao/Deployment_RepositoryManager.idl" + +module CIAO +{ + interface RepositoryManagerDaemon : Deployment::RepositoryManager + { + // Shutdown the daemon process. + oneway void shutdown (); + }; +}; + diff --git a/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.cpp b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.cpp new file mode 100644 index 00000000000..91aa4e47460 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.cpp @@ -0,0 +1,1267 @@ +// $Id$ + +//==================================================================== +/** + * @file RepositoryManager_Impl.cpp + * + * $Id$ + * + * Description: Actial implementation of the RepoMan + * + * @author Stoyan Paunov + * Shanshan Jiang <shanshan.jiang@vanderbilt.edu> + */ +//==================================================================== + +#include "RepositoryManager_Impl.h" + +#include "ace/OS_NS_fcntl.h" //for open +#include "ace/OS_NS_unistd.h" //for close +#include "ace/OS_NS_sys_stat.h" //for filesize and fstat and mkdir +#include "ace/OS_NS_string.h" //for ACE_CString +#include "ace/OS_Memory.h" //for ACE_NEW* macros + + +//to remove a file or dir from the local filesystem need remove () from stdio.h +// ---> need to include ace/OS_NS_stdio.h which would include the correct file for any OS! +#include "ace/OS_NS_stdio.h" + +#include "ZIP_Wrapper.h" //Wrapper around zzip +#include "ace/Containers_T.h" //for ACE_Double_Linked_List +#include "ace/Malloc_Allocator.h" //for ACE_New_Allocator + +//for the PackageConfiguration parsing +#include "ciao/Deployment_DataC.h" +#include "ciao/Deployment_Packaging_DataC.h" +#include "Package_Handlers/PCD_Handler.h" + +#include "RM_Helper.h" //to be able to externalize/internalize a PackageConfiguration +#include "ace/Message_Block.h" //for ACE_Message_Block + +#include "ace/Thread.h" //for obtaining the ID of the current thread +#include "ace/OS_NS_stdlib.h" //for itoa () + +#include "URL_Parser.h" //for parsing the URL +#include "tao/HTTP_Client.h" //the HTTP client class to downloading packages + +#include "PC_Updater.h" //A visitor class to walk through the elements of the PC + +#include "ace/Configuration_Import_Export.h" + +namespace +{ + static const char* PC_EXTENSION = ".epc"; + + static const char *RM_RECORD_FILE = "RM_record"; + static const char *RM_RECORD_NAME_SECTION = "Names"; + static const char *RM_RECORD_UUID_SECTION = "UUIDs"; +} + +//----------------------------------------------------------------- +//Constructor +// +//----------------------------------------------------------------- + +CIAO_RepositoryManagerDaemon_i::CIAO_RepositoryManagerDaemon_i + (CORBA::ORB_ptr the_orb, const char* server, const char* install_dir) + : the_orb_ (CORBA::ORB::_duplicate (the_orb)), + install_root_ (""), + HTTP_server_ ("http://"), + install_path (install_dir) +{ + //form the path + this->HTTP_server_ += server; + this->HTTP_server_ += "/"; + this->HTTP_server_ += install_path; + this->HTTP_server_ += "/"; + + //create directory in which the packages will be stored + ACE_OS::mkdir(install_path.c_str ()); + //if dir already exists a -1 is returned + //we ignore this, just need to make sure the directory exists + + ACE_OS::getcwd (this->cwd_, TEMP_LEN); + + this->install_root_ = this->cwd_; + this->install_root_ += "/"; + this->install_root_ += install_path; + + // Install the configuration files to get the names, UUIDs, & types info. + ACE_Configuration_Heap cfg; + cfg.open (); + ACE_Configuration_Section_Key root = cfg.root_section (); + + ACE_Registry_ImpExp config_importer (cfg); + ACE_OS::chdir (install_path.c_str ()); + config_importer.import_config (RM_RECORD_FILE); + ACE_OS::chdir (this->cwd_); + + ACE_CString name; + ACE_Configuration::VALUETYPE type; + ACE_CString path; + + ACE_Configuration_Section_Key NameSection; + cfg.open_section (root, RM_RECORD_NAME_SECTION, 1, NameSection); + u_int index = 0; + while (!cfg.enumerate_values (NameSection, index, name, type)) + { + cfg.get_string_value (NameSection, name.c_str (), path); + this->names_.bind (name, path); + + ++index; + } + + ACE_Configuration_Section_Key UUIDSection; + cfg.open_section (root, RM_RECORD_UUID_SECTION, 1, UUIDSection); + index = 0; + while (!cfg.enumerate_values (UUIDSection, index, name, type)) + { + cfg.get_string_value (UUIDSection, name.c_str (), path); + this->uuids_.bind (name, path); + + ++index; + } + + // Add types + index = 0; + for (PCMap_Iterator iter = this->names_.begin (); + iter != this->names_.end (); + ++iter, ++index) + { + PCEntry& element = *iter; + + ::Deployment::PackageConfiguration_var pc = this->findPackageByName (element.ext_id_.c_str ()); + + if(!this->add_type (pc, element.ext_id_.c_str ())) + ACE_ERROR ((LM_ERROR, "Failed to add the type\n")); + } +} + +//----------------------------------------------------------------- +//Destructor +// +//----------------------------------------------------------------- + +CIAO_RepositoryManagerDaemon_i::~CIAO_RepositoryManagerDaemon_i (void) +{ + this->names_.unbind_all (); + this->uuids_.unbind_all (); + this->types_.unbind_all (); +} + +//----------------------------------------------------------------- +//shutdown +// +//----------------------------------------------------------------- + +void CIAO_RepositoryManagerDaemon_i::shutdown () + + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // Save the names, UUIDs, & types info to the configuration files. + ACE_Configuration_Heap cfg; + cfg.open (); + ACE_Configuration_Section_Key root = cfg.root_section (); + + ACE_Configuration_Section_Key NameSection; + cfg.open_section (root, RM_RECORD_NAME_SECTION, 1, NameSection); + for (PCMap_Iterator iter = this->names_.begin (); + iter != this->names_.end (); + ++iter) + { + PCEntry& element = *iter; + cfg.set_string_value (NameSection, element.ext_id_.c_str (), element.int_id_.c_str ()); + } + + ACE_Configuration_Section_Key UUIDSection; + cfg.open_section (root, RM_RECORD_UUID_SECTION, 1, UUIDSection); + for (PCMap_Iterator iter = this->uuids_.begin (); + iter != this->uuids_.end (); + ++iter) + { + PCEntry& element = *iter; + cfg.set_string_value (UUIDSection, element.ext_id_.c_str (), element.int_id_.c_str ()); + } + + ACE_Registry_ImpExp exporter (cfg); + ACE_OS::chdir (install_path.c_str ()); + exporter.export_config (RM_RECORD_FILE); + ACE_OS::chdir (this->cwd_); + + // Release resource. + this->names_.unbind_all (); + this->uuids_.unbind_all (); + this->types_.unbind_all (); + + this->the_orb_->shutdown (0); +} + + +//----------------------------------------------------------------- +//installPackage +// +//----------------------------------------------------------------- + +void CIAO_RepositoryManagerDaemon_i::installPackage ( + const char * installationName, + const char * location, + ::CORBA::Boolean replace + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NameExists, + ::Deployment::PackageError + )) +{ + + PCEntry *entry = 0; + if (this->names_.find (ACE_CString (installationName), entry) == 0) + { + if (!replace) + throw Deployment::NameExists (); + else + deletePackage (installationName); + } + + //Now lets form the path for the local file + //NOTE: I need the absolute path because I will change to a subdirectory + //when I am parsing the descriptors + + ACE_CString path (this->install_root_); + path += "/"; + path += installationName; + + ACE_CString package_path (path); + package_path += ".cpk"; //package extension + + ACE_CString pc_path (path); + pc_path += PC_EXTENSION; //external PackageConfiguration extension + + + ACE_CString descriptor_dir (path); + descriptor_dir += "/descriptors/"; //location of the descriptor directory + + + //check if URL or local file + //download or load into memory + + if (ACE_OS::strstr (location, "http://")) + { + + //TODO: how can I incorporate a Auto_Ptr is explicit release is needed + ACE_Message_Block* mb = 0; + ACE_NEW_THROW_EX (mb, ACE_Message_Block (), CORBA::NO_MEMORY ()); + + //get the remote file + if (!HTTP_Get (location, *mb)) + { + mb->release (); + throw CORBA::INTERNAL (); + } + + // Write file to designated location on disk + if (!RM_Helper::write_to_disk (package_path.c_str (), *mb)) + { + mb->release (); + throw CORBA::INTERNAL (); + } + + mb->release (); + } + else + { + if (!RM_Helper::copy_from_disk_to_disk (location, package_path.c_str ())) + throw CORBA::INTERNAL (); + } + + + ZIP_Wrapper::uncompress (const_cast<char*> (package_path.c_str ()), + const_cast<char*> (this->install_root_.c_str ()), + false //not verbose + ); + + //Start the parsing + + ACE_CString pc_name; + + this->find_PC_name (const_cast<char*> (package_path.c_str ()), pc_name); + + //if the PackageConfiguration name cannot be found, then there is nothing to install + if (pc_name == "") + { + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + + throw Deployment::PackageError (); + } + + //TODO: move exception throwing out of this func. User boolean error handling!!! + //TODO: check for errors! + Deployment::PackageConfiguration_var pc; + pc = this->retrieve_PC_from_descriptors (const_cast<char*> (pc_name.c_str ()), + descriptor_dir.c_str ()); + + + if (this->uuids_.find (ACE_CString (pc->UUID), entry) == 0) + { + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + + throw Deployment::NameExists (); + } + + //forming the server path info + ACE_CString server_path (this->HTTP_server_); + server_path += installationName; + + //NOTE: ComponentPackageReferences are currently NOT supported + if (!(pc->basePackage.length () > 0)) + { + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + + throw CORBA::NO_IMPLEMENT (); + } + + PC_Updater updater (server_path, package_path); + + if (!updater.update (pc)) + { + ACE_DEBUG ((LM_ERROR, "[RM] problem updating the PackageConfiguration!\n")); + + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + throw Deployment::PackageError (); + } + + + //now lets externalize the PackageConfiguration, so that we can access it later on + //without having to do the whole parsing again. + //NOTE: Order here is important. Do not populate maps before the externalization! + RM_Helper::externalize (pc, pc_path.c_str ()); + + //insert the package into the database + if (this->names_.bind (ACE_CString (installationName), path) == -1) + { + ACE_ERROR ((LM_ERROR, + "[RM] could not bind %s.\n", + installationName)); + + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + //remove the PackageConfiguration externalization + remove (pc_path.c_str ()); + + //throw exception + throw CORBA::INTERNAL (); + } + + //ALSO NEED THE UUID here + if (this->uuids_.bind (ACE_CString (pc->UUID), path) == -1) + { + ACE_ERROR ((LM_ERROR, + "[RM] could not bind %s.\n", + ACE_CString (pc->UUID).c_str ())); + + //unbind the name + this->names_.unbind (installationName); + + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + //remove the PackageConfiguration externalization + remove (pc_path.c_str ()); + + //throw exception + throw CORBA::INTERNAL (); + } + + //now add the type interface + if(!this->add_type (pc, installationName)) + ACE_ERROR ((LM_ERROR, "Failed to add the type\n")); + + this->dump (); + + ACE_DEBUG ((LM_INFO, + "Installed PackageConfiguration \n\tname: %s \n\tuuid: %s\n", + installationName, ACE_CString (pc->UUID).c_str ())); +} + + +//----------------------------------------------------------------- +//createPackage +// +//----------------------------------------------------------------- + +void CIAO_RepositoryManagerDaemon_i::createPackage ( + const char * installationName, + const ::Deployment::PackageConfiguration & package, + const char * baseLocation, + ::CORBA::Boolean replace + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NameExists, + ::Deployment::PackageError + )) +{ + ::Deployment::PackageConfiguration pc = package; + + // Find if there is a PackageConfiguration with the same name. + PCEntry *entry = 0; + if (this->names_.find (ACE_CString (installationName), entry) == 0) + { + if (!replace) + throw Deployment::NameExists (); + else + deletePackage (installationName); + } + + // Find if there is a PackageConfiguration with the same uuid. + if (this->uuids_.find (ACE_CString (pc.UUID), entry) == 0) + throw Deployment::NameExists (); + + // Find if the PackageConfiguration has a basePackage. + // NOTE: ComponentPackageReferences are currently NOT supported. + if (!(pc.basePackage.length () > 0)) + throw CORBA::NO_IMPLEMENT (); + + // Form the path for the local file + ACE_CString path (this->install_root_); + path += "/"; + path += installationName; + + ACE_CString package_path (path); + package_path += ".cpk"; //package extension + + ACE_CString pc_path (path); + pc_path += PC_EXTENSION; //external PackageConfiguration extension + + // Check if URL or local file, download or load into memory + if (ACE_OS::strstr (baseLocation, "http://")) + { + //TODO: how can I incorporate a Auto_Ptr is explicit release is needed + ACE_Message_Block* mb; + ACE_NEW_THROW_EX (mb, ACE_Message_Block (), CORBA::NO_MEMORY ()); + + //get the remote file + if (!HTTP_Get (baseLocation, *mb)) + { + mb->release (); + throw CORBA::INTERNAL (); + } + + // Write file to designated location on disk + if (!RM_Helper::write_to_disk (package_path.c_str (), *mb)) + { + mb->release (); + throw CORBA::INTERNAL (); + } + + mb->release (); + } + else + { + if (!RM_Helper::copy_from_disk_to_disk (baseLocation, package_path.c_str ())) + throw CORBA::INTERNAL (); + } + + + ZIP_Wrapper::uncompress (const_cast<char*> (package_path.c_str ()), + const_cast<char*> (this->install_root_.c_str ()), + false //not verbose + ); + + // Form the server path info + ACE_CString server_path (this->HTTP_server_); + server_path += installationName; + + // Update the newly installed package configration informantion. + PC_Updater updater (server_path, package_path); + + if (!updater.update (pc)) + { + ACE_ERROR ((LM_ERROR, "[RM] problem updating the PackageConfiguration!\n")); + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + throw Deployment::PackageError (); + } + + // Externalize the PackageConfiguration, so that we can access it later on + // without having to do the whole parsing again. + // NOTE: Order here is important. Do not populate maps before the externalization! + RM_Helper::externalize (pc, pc_path.c_str ()); + + // Insert the name of the package. + if (this->names_.bind (ACE_CString (installationName), path) == -1) + { + ACE_ERROR ((LM_ERROR, + "[RM] could not bind %s.\n", + installationName)); + + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + //remove the PackageConfiguration externalization + remove (pc_path.c_str ()); + + //throw exception + throw CORBA::INTERNAL (); + } + + // Insert the UUID of the package. + if (this->uuids_.bind (ACE_CString (pc.UUID), path) == -1) + { + ACE_ERROR ((LM_ERROR, + "[RM] could not bind %s.\n", + ACE_CString (pc.UUID).c_str ())); + + //unbind the name + this->names_.unbind (installationName); + + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + //remove the PackageConfiguration externalization + remove (pc_path.c_str ()); + + //throw exception + throw CORBA::INTERNAL (); + } + + //now add the type interface + //TODO: CHECK if successful + if(!this->add_type (pc, installationName)) + ACE_ERROR ((LM_ERROR, "Failed to add the type\n")); + + this->dump (); + + ACE_DEBUG ((LM_INFO, + "Created PackageConfiguration \n directory: %s \n name: %s \n uuid: %s\n", + path.c_str (), installationName, ACE_CString (pc.UUID).c_str ())); +} + + +//----------------------------------------------------------------- +//findPackageByName +// +//----------------------------------------------------------------- + +::Deployment::PackageConfiguration* +CIAO_RepositoryManagerDaemon_i::findPackageByName (const char * name) + + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NoSuchName + )) +{ + // Find out if the PackageConfiguration was installed in the repository, + // return it if found or throw and exception otherwise + + PCEntry *entry = 0; + + if (this->names_.find (ACE_CString (name), entry) != 0) + throw Deployment::NoSuchName (); + //PackageConfiguration was not found + + ACE_CString pc_path (entry->int_id_.c_str ()); + pc_path += PC_EXTENSION; + + Deployment::PackageConfiguration_var pc; + ACE_NEW_THROW_EX (pc, + Deployment::PackageConfiguration (), + CORBA::NO_MEMORY ()); + + + if(!RM_Helper::reincarnate (pc, pc_path.c_str ())) + ACE_THROW_RETURN (CORBA::INTERNAL (), 0); + + ACE_DEBUG ((LM_INFO, "Successfully looked up \'%s\'.\n", name)); + + return pc._retn (); +} + + +//----------------------------------------------------------------- +//findPackageByUUID +// +//----------------------------------------------------------------- + +::Deployment::PackageConfiguration* +CIAO_RepositoryManagerDaemon_i::findPackageByUUID (const char * UUID) + + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NoSuchName + )) +{ + // Find out if the PackageConfiguration was installed in the repository, + // return it if found or throw and exception otherwise + + PCEntry *entry = 0; + + if (this->uuids_.find (ACE_CString (UUID), entry) != 0) + throw Deployment::NoSuchName (); + //PackageConfiguration was not found + + ACE_CString pc_path (entry->int_id_.c_str ()); + pc_path += PC_EXTENSION; + + Deployment::PackageConfiguration_var pc; + ACE_NEW_THROW_EX (pc, + Deployment::PackageConfiguration (), + CORBA::NO_MEMORY ()); + + + if(!RM_Helper::reincarnate (pc, pc_path.c_str ())) + ACE_THROW_RETURN (CORBA::INTERNAL (), 0); + + ACE_DEBUG ((LM_INFO, "Successfully looked up %s.\n", UUID)); + + return pc._retn (); +} + +//----------------------------------------------------------------- +//findPackageByType +// +//----------------------------------------------------------------- + +::CORBA::StringSeq * CIAO_RepositoryManagerDaemon_i::findNamesByType ( + const char * type + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + CIEntry *entry = 0; + + //find the type in the interface map + if (this->types_.find (ACE_CString (type), entry) != 0) + { + //return an empty sequence + CORBA::StringSeq_var seq; + ACE_NEW_THROW_EX (seq, CORBA::StringSeq (0), CORBA::NO_MEMORY ()); + + return seq._retn (); + } + else + { + CISet ci_set = (*entry).int_id_set_; + + CORBA::ULong len = ci_set.size (); + + //allocate a sequence of the right length + CORBA::StringSeq_var seq; + ACE_NEW_THROW_EX (seq, + CORBA::StringSeq (len), + CORBA::NO_MEMORY ()); + seq->length (len); + + //store the elements in the string sequence + CISet_Iterator ci_set_iter (ci_set); + CORBA::ULong index = 0; + for (ci_set_iter = ci_set.begin (); + ci_set_iter != ci_set.end () && index < len; + ++ci_set_iter, ++index) + { + seq[index] = CORBA::string_dup ((*ci_set_iter).c_str ()); + } + + return seq._retn (); + } +} + + +//----------------------------------------------------------------- +//getAllNames +// +//----------------------------------------------------------------- + +::CORBA::StringSeq* +CIAO_RepositoryManagerDaemon_i::getAllNames () + + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + //Map.current_size () gives you the current number with the duplicates + //Map.total_size () gives you the allocated space + the empty slots + //Apparently the only way to figure out the number of keys is to + //count them with an iterator. + + CORBA::ULong num_entries = 0; + + for (PCMap_Iterator i = this->names_.begin (); + i != this->names_.end (); + ++i) + ++num_entries; + + CORBA::StringSeq_var seq; + ACE_NEW_THROW_EX (seq, CORBA::StringSeq (num_entries), CORBA::NO_MEMORY ()); + + + seq->length (num_entries); + + CORBA::ULong index = 0; + for (PCMap_Iterator iter = this->names_.begin (); + iter != this->names_.end () && index < num_entries; + ++iter, ++index) + { + PCEntry& element = *iter; + seq[index] = CORBA::string_dup (element.ext_id_.c_str ()); + } + + ACE_DEBUG ((LM_INFO, "The number of packages %d\n", seq->length ())); + + return seq._retn (); //release the underlying CORBA::StringSeq +} + + +//----------------------------------------------------------------- +//getAllTypes +// +//----------------------------------------------------------------- + +::CORBA::StringSeq * CIAO_RepositoryManagerDaemon_i::getAllTypes ( + + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + //Map.current_size () gives you the current number with the duplicates + //Map.total_size () gives you the allocated space + the empty slots + //Apparently the only way to figure out the number of keys is to + //count them with an iterator. + + CORBA::ULong num_entries = 0; + + for (CIMap_Iterator i = this->types_.begin (); + i != this->types_.end (); + ++i) + ++num_entries; + + CORBA::StringSeq_var seq; + ACE_NEW_THROW_EX (seq, + CORBA::StringSeq (num_entries), + CORBA::NO_MEMORY ()); + + + seq->length (num_entries); + + CORBA::ULong index = 0; + for (CIMap_Iterator iter = this->types_.begin (); + iter != this->types_.end () && index < num_entries; + ++iter, ++index) + + { + CIEntry& element = *iter; + seq[index] = CORBA::string_dup (element.ext_id_.c_str ()); + } + + ACE_DEBUG ((LM_DEBUG, "The number of types: %d\n", num_entries)); + + return seq._retn (); //release the underlying CORBA::StringSeq +} + + +//----------------------------------------------------------------- +//DeletePackage +// +//----------------------------------------------------------------- + +void CIAO_RepositoryManagerDaemon_i::deletePackage ( + const char * installationName + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NoSuchName + )) +{ + bool internal_err = false; + + PCEntry *entry = 0; + + if (this->names_.find (ACE_CString (installationName), entry) != 0) + throw Deployment::NoSuchName (); + + //cache the package path + ACE_CString path (entry->int_id_.c_str ()); + + //remove the name association + if (this->names_.unbind (installationName) == -1) + { + ACE_ERROR ((LM_ERROR, + "Unable to unbind %s.\n", + installationName)); + internal_err = true; + } + + //the package location + ACE_CString package_path (path); + package_path += ".cpk"; //package extension + + //the PackageConfiguration externalization location + ACE_CString pc_path (path); + pc_path += PC_EXTENSION; //external PackageConfiguration extension + + Deployment::PackageConfiguration_var pc; + ACE_NEW_THROW_EX (pc, + Deployment::PackageConfiguration (), + CORBA::NO_MEMORY ()); + + + if(!RM_Helper::reincarnate (pc, pc_path.c_str ())) + { + ACE_ERROR ((LM_ERROR, "Could not reincarnate PC\n")); + internal_err = true; + } + + if (this->uuids_.unbind (ACE_CString (pc->UUID)) == -1) + { + ACE_ERROR ((LM_ERROR, "Could not remove UUID\n")); + internal_err = true; + } + + //remove the type from the interface map + if (!this->remove_type (pc, installationName)) + { + ACE_ERROR ((LM_ERROR, "Could not remove type\n")); + internal_err = true; + } + + //actually delete the package here! + + //clean the extracted files + remove_extracted_package (package_path.c_str (), path.c_str ()); + //remove the package + remove (package_path.c_str ()); + //remove the PackageConfiguration externalization + remove (pc_path.c_str ()); + + this->dump (); + + if (internal_err) + throw CORBA::INTERNAL (); + else + ACE_DEBUG ((LM_INFO, "Successfully deleted \'%s\'\n", installationName)); + +} + + +//==========================================HELPER METHODS================================================== + +Deployment::PackageConfiguration* +CIAO_RepositoryManagerDaemon_i::retrieve_PC_from_package (char* package) +{ + char temp[128]; + // ACE_thread_t thread_id = ACE_Thread::self (); + char* PID = ACE_OS::itoa (ACE_OS::getpid (), temp, 10); + + ACE_OS::mkdir(PID); + //if dir already exists a -1 is returned + //we ignore this, just need to make sure the directory exists + + //change the working dir + ACE_OS::chdir (PID); + + ACE_CString pcd_name; + //extract the necessary descriptors + if (extract_descriptor_files (package, + pcd_name) < 0) + { + ACE_OS::chdir (this->cwd_); + ACE_ERROR ((LM_ERROR, + "(%P|%t) RepositoryManager: error extracting necessary files\n")); + throw CORBA::INTERNAL (); + } + + Deployment::PackageConfiguration_var pc; + //parse the PCD to make sure that there are no package errors + try + { + //CIAO::Config_Handlers::STD_PC_Intf intf (pcd_name.c_str ()); + //pc = intf.get_PC (); + } + catch (...) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) RepositoryManager: Error parsing the PCD\n")); + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + throw Deployment::PackageError (); + } + //able to parse the PC. So lets install the package in the repo + + //we no longer need the descriptors, so lets erase them! + remove_descriptor_files (package); + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + + //now lets erase the directory! + ACE_OS::rmdir (PID); + //the ACE_OS::rmdir does not work. Possibly because we need to delete + //the contents first. I will look into it more closely when I am back. + + return pc._retn (); +} + + +//function to retvieve a file via HTTP +//stores the file in the passed preallocated ACE_Message_Block +//returns 1 on success +// 0 on error + +int CIAO_RepositoryManagerDaemon_i::HTTP_Get (const char* URL, ACE_Message_Block &mb) +{ + URL_Parser *parser = TheURL_Parser::instance (); + if (!parser->parseURL (const_cast<char*> (URL))) + return 0; + + // Create a client + TAO_HTTP_Client client; + + // Open the client + if (client.open (parser->filename_, + parser->hostname_, + parser->port_) == -1) + { + client.close (); + return 0; + } + + // Read from it + if (client.read (&mb) <= 0) + { + client.close (); + return 0; + } + + return 1; +} + + + +//function to parse and return the PackageConfiguration from the already +//extracted descriptor files +Deployment::PackageConfiguration* +CIAO_RepositoryManagerDaemon_i::retrieve_PC_from_descriptors (const char* pc_name, + const char* descriptor_dir) +{ + //change the working dir + ACE_OS::chdir (descriptor_dir); + + Deployment::PackageConfiguration_var pc = new Deployment::PackageConfiguration (); + //parse the PCD to make sure that there are no package errors + try + { + CIAO::Config_Handlers::Packaging::PCD_Handler::package_config (pc_name, *pc); + } + catch (...) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) [RM::retrieve_PC_from_descriptors] Error parsing the PCD\n")); + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + throw Deployment::PackageError (); + } + //able to parse the PC. So lets install the package in the repo + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + + return pc._retn (); +} + + +//find out what the name of the PackageConfiguration file is +void CIAO_RepositoryManagerDaemon_i::find_PC_name (char* package, ACE_CString& pcd_name) +{ + pcd_name = ""; //empty the contents of the ACE_CString + + //create a doubly link list + ACE_New_Allocator allocator; + ACE_Double_Linked_List<ZIP_File_Info> list (&allocator); + + //get the list of files in the package and figure out the names of all necessary files + if (!(ZIP_Wrapper::file_list_info (package, list))) + return; + + size_t skip_len = ACE_OS::strlen ("descriptors") + 1; + + while (!list.is_empty ()) + { + ZIP_File_Info* inf = list.delete_head (); + + if (ACE_OS::strstr (inf->name_.c_str (), "descriptors")) + if (ACE_OS::strstr (inf->name_.c_str (), ".pcd")) + pcd_name = inf->name_.c_str () + skip_len; + + //deallocate the head of the filename list + delete inf; + } +} + + +//We are using Xercesc in the Config_Handlers and unfortunately its API only +//takes a file in the local file system as an argument, thus need to +//write out the contents of the deployent plan to a file +//in the current directory. I use the thread id to guarrantee +//lack of race conditions if multithreading is enabled + +int CIAO_RepositoryManagerDaemon_i::extract_descriptor_files (char* package, ACE_CString& pcd_name) +{ + //create a doubly link list + ACE_New_Allocator allocator; + ACE_Double_Linked_List<ZIP_File_Info> list (&allocator); + + //get the list of files in the package and figure out the names of all necessary files + if (!(ZIP_Wrapper::file_list_info (package, list))) + return 0; + + size_t skip_len = ACE_OS::strlen ("descriptors") + 1; + + while (!list.is_empty ()) + { + ZIP_File_Info* inf = list.delete_head (); + ACE_Message_Block* file = 0; + if (ACE_OS::strstr (inf->name_.c_str (), "descriptors")) + { + if (ACE_OS::strstr (inf->name_.c_str (), ".pcd")) + pcd_name = inf->name_.c_str () + skip_len; + + //extract the descriptor from the package + ACE_NEW_RETURN (file, ACE_Message_Block (0,0), 0); + if (!ZIP_Wrapper::get_file(const_cast<char*> (package), + const_cast<char*> (inf->name_.c_str ()), + *file)) + { + ACE_ERROR ((LM_ERROR, + "[RM::extract_descriptor_files] Unable to retrieve file!\n")); + //release the message block chain + file->release (); + return 0; + } + + + //write the file to disk + if(!RM_Helper::write_to_disk (inf->name_.c_str () + skip_len, *file)) + { + ACE_ERROR ((LM_ERROR, + "[RM::extract_descriptor_files] Unable to write out descriptor to disk!\n")); + //release the message block chain + file->release (); + return 0; + } + + //release the message block chain + file->release (); + } + + //deallocate the head of the filename list + delete inf; + } + + return 1; +} + +int CIAO_RepositoryManagerDaemon_i::remove_descriptor_files (char* package) +{ + int return_code = 1; + + //create a doubly link list + ACE_New_Allocator allocator; + ACE_Double_Linked_List<ZIP_File_Info> list (&allocator); + + //get the list of files in the package and figure out the names of all necessary files + if (!(ZIP_Wrapper::file_list_info (package, list))) + return 0; + + size_t skip_len = ACE_OS::strlen ("descriptors") + 1; + + while (!list.is_empty ()) + { + ZIP_File_Info* inf = list.delete_head (); + if (ACE_OS::strstr (inf->name_.c_str (), "descriptors")) + { + //delete disk + if(remove (inf->name_.c_str () + skip_len)) + { + ACE_ERROR ((LM_ERROR, + "[RM::remove_descriptor_files] Unable to remove file from disk!\n")); + return_code = 0; + } + } + //deallocate the head of the filename list + delete inf; + } + + return return_code; +} + +//function to remove the files extracted from the package upon istallation +//It reads the names of the files from the package. They correspond to the +//names on disk. It deletes each file, then it deletes the directories that +//contain them. +//return 1 on success +// 0 on error + +int CIAO_RepositoryManagerDaemon_i::remove_extracted_package + (const char* package_path, + const char* extraction_location) +{ + //change the working dir + if (ACE_OS::chdir (extraction_location) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "[RM::remove_extracted_package] Unable to chdir to doomed directory!\n"), + 0); + + int return_code = 1; + + //create a doubly link list + ACE_New_Allocator allocator; + ACE_Double_Linked_List<ZIP_File_Info> list (&allocator); + + //get the list of files in the package and figure out the names of all necessary files + if (!(ZIP_Wrapper::file_list_info (const_cast <char*> (package_path), list))) + { + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + return 0; + } + + while (!list.is_empty ()) + { + ZIP_File_Info* inf = list.delete_head (); + + //delete file from disk + if(remove (inf->name_.c_str ())) + { + ACE_ERROR ((LM_ERROR, + "[RM::remove_extracted files] Unable to delete %s!\n", inf->name_.c_str ())); + return_code = 0; + } + + //deallocate the head of the filename list + delete inf; + } + + //now remove the descriptors and implementations directories. + ACE_OS::rmdir ("descriptors"); + ACE_OS::rmdir ("implementations"); + + //now go one directory up and delete the extraction directory + ACE_OS::chdir (this->install_root_.c_str ()); + ACE_OS::rmdir (extraction_location); + + //change back the the old working dir + ACE_OS::chdir (this->cwd_); + + return return_code; +} + +//function to extract the type of the component from +//the PackageConfiguration and update the interface map +//returns 1 on success +// 0 on error + +int CIAO_RepositoryManagerDaemon_i::add_type (Deployment::PackageConfiguration& pc, + const char* name) +{ + if (pc.basePackage.length () > 0) + { + ::CORBA::StringSeq supportedTypes = pc.basePackage[0] + .implementation[0] + .referencedImplementation + .implements + .supportedType; + + if (supportedTypes.length () != 0) + { + CORBA::ULong len = supportedTypes.length (); + for (CORBA::ULong i = 0; i < len; ++i) + { + this->types_.bind (ACE_CString (supportedTypes[i]), name); + } + } + } + else //ComponentPackageReference + { + //not implemented yet + return 0; + } + + return 1; +} + +//function to remove the interface type of the component +//being removed from the interface map +//returns 1 on success +// 0 on error + +int CIAO_RepositoryManagerDaemon_i::remove_type (Deployment::PackageConfiguration& pc, + const char* name) +{ + if (pc.basePackage.length () > 0) + { + ::CORBA::StringSeq supportedTypes = pc.basePackage[0] + .implementation[0] + .referencedImplementation + .implements + .supportedType; + + if (supportedTypes.length () != 0) + { + CORBA::ULong len = supportedTypes.length (); + for (CORBA::ULong i = 0; i < len; ++i) + { + if (this->types_.unbind (ACE_CString (supportedTypes[i]), ACE_CString (name)) != 0) + ACE_DEBUG ((LM_DEBUG, "Could not find type %s with package name %s!\n", + ACE_CString (supportedTypes[i]).c_str (), + name)); + } + } + } + else //ComponentPackageReference + { + //not implemented yet + return 0; + } + + return 1; +} + +//function to dump the state of the RepositoryManager +void CIAO_RepositoryManagerDaemon_i::dump (void) +{ +#if defined (ACE_HAS_DUMP) + + ACE_DEBUG(LM_DEBUG, "NAMES:\n"); + this->names_.dump (); + ACE_DEBUG(LM_DEBUG, "UUIDs:\n"); + this->uuids_.dump (); + ACE_DEBUG (LM_DEBUG, "Component Interface Types:\n"); + this->types_.dump (); + +#endif /* ACE_HAS_DUMP */ +} diff --git a/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.h b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.h new file mode 100644 index 00000000000..0c371d7c758 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/RepositoryManager_Impl.h @@ -0,0 +1,280 @@ + +/* -*- C++ -*- */ + +//====================================================================== +/** + * @file RepositoryManager_Impl.h + * + * $Id$ + * + * Description: + * This file is the main implementation file for the RepositoryManager + * in CIAO. We have used a number of techniques in order to increase + * scalability of the RepoMan while still maintaining complience with + * the D&C spec + * + * @author Stoyan Paunov + * Shanshan Jiang <shanshan.jiang@vanderbilt.edu> + */ +//====================================================================== + +#ifndef REPOSITORYMANAGERI_H_ +#define REPOSITORYMANAGERI_H_ + + +//-----------------------------NOTE--------------------------------- +//I need to disable all the code which has to do with interface +//type information because we currently do not support assembly +//interfaces which causes undesired behavior with respect to the +//hash tables because the specificType field in assembly interfaces +//is empty, so two unrelated intefaces appear to be related. + + +#include "RepositoryManagerDaemonS.h" + +#include "ace/Hash_Map_Manager_T.h" //for the ACE_Hash_Map_Manager +#include "ace/Hash_Multi_Map_Manager_T.h" //for the ACE_Hash_MultiMap_Manager +#include "ace/Null_Mutex.h" //for ACE_Null_Mutex +#include "ace/RW_Mutex.h" //for ACE_RW_Mutex +#include "ace/OS_NS_string.h" //for ACE_CString +#include "ace/SString.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace +{ + static const size_t TEMP_LEN = 1024; +} + +class CIAO_RepositoryManagerDaemon_i : + public virtual POA_CIAO::RepositoryManagerDaemon +{ +public: + /// Constructor + CIAO_RepositoryManagerDaemon_i (CORBA::ORB_ptr the_orb, + const char* server = "localhost:5432", + const char* install_dir = "RepositoryManager"); + + /// Destructor + virtual ~CIAO_RepositoryManagerDaemon_i (void); + + virtual + void shutdown ( + + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + virtual + void installPackage ( + const char * installationName, + const char * location, + ::CORBA::Boolean replace + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NameExists, + ::Deployment::PackageError + )); + + virtual + void createPackage ( + const char * installationName, + const ::Deployment::PackageConfiguration & package, + const char * baseLocation, + ::CORBA::Boolean replace + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NameExists, + ::Deployment::PackageError + )); + + virtual + ::Deployment::PackageConfiguration * findPackageByName ( + const char * name + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NoSuchName + )); + + virtual + ::Deployment::PackageConfiguration * findPackageByUUID ( + const char * UUID + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NoSuchName + )); + + virtual + ::CORBA::StringSeq * findNamesByType ( + const char * type + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + virtual + ::CORBA::StringSeq * getAllNames ( + + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + virtual + ::CORBA::StringSeq * getAllTypes ( + + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + virtual + void deletePackage ( + const char * installationName + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + ::Deployment::NoSuchName + )); + +protected: + + /// Function to parse and return the PackageConfiguration from a specified + /// package + Deployment::PackageConfiguration* retrieve_PC_from_package (char* package); + + /// Find out what the name of the PackageConfiguration file is + void find_PC_name (char* package, ACE_CString& pcd_name); + + /// Function to parse and return the PackageConfiguration from the already + /// extracted descriptor files + Deployment::PackageConfiguration* retrieve_PC_from_descriptors (const char* pc_name, + const char* descriptor_dir); + + + /// Function to retrieve a file via HTTP + /// stores the file in the passed preallocated ACE_Message_Block + /// @retval 1 success + /// @retval 0 error + int HTTP_Get (const char* URL, ACE_Message_Block &mb); + + /// Function to extract all necessary files for parsing the + /// PackageConfiguration descriptor and populating the idl struct. + /// @retval 1 success + /// @retval 0 error + /// + /// @note ACE_CString& pcd_name is an out parameter + int extract_descriptor_files (char* package, + ACE_CString& pcd_name); + + + /// Function to remove the files extracted for parsing the PackageConfiguration + /// descriptor and populating the idl struct. It reads the names of the files + /// from the package. They correspond to the names on disk. + /// @retval 1 on success + /// @retval 0 on error + int remove_descriptor_files (char* package); + + + /// Function to remove the files extracted from the package upon istallation + /// It reads the names of the files from the package. They correspond to the + /// names on disk. It deletes each file, then it deletes the directories that + /// contain them. + /// @note extraction location is path/*archive_name*/ + /// @retval 1 on success + /// @retval 0 on error + int remove_extracted_package (const char* package_path, const char* extraction_location); + + /// Function to extract the type of the component from + /// the PackageConfiguration and update the interface map + /// @retval 1 on success + /// @retval 0 on error + int add_type (::Deployment::PackageConfiguration& pc, + const char* name); + + /// Function to remove the interface type of the component + /// being removed from the interface map + /// @retval 1 on success + /// @retval 0 on error + int remove_type (::Deployment::PackageConfiguration& pc, + const char* name); + + /// Function to dump the state of the RepositoryManager + void dump (void); + +private: + /// Cached information about the installed PackageConfigurations + /// A separate map for the installation names and their UUID's + /// Key: PackageConfiguration name or its UUID (CString type) + /// Value: The location of the local copy of the package + + ///Based on the synchronization needed we can parametrize this with either + ///ACE_Null_Mutex or ACE_RW_Mutex + + typedef ACE_Hash_Map_Manager_Ex<ACE_CString, + ACE_CString, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_RW_Mutex> PCMap; + + typedef PCMap::ITERATOR PCMap_Iterator; + typedef PCMap::ENTRY PCEntry; + + + /// Cached information about the installed Component Interfaces + /// A map which associates Component supportedType with the + /// names of packages which implement this component type + /// Key: Component supportedType + /// Value: Unbounded set of the names of installed packages which + /// implement this component type + + ///Based on the synchronization needed we can parametrize this with either + ///ACE_Null_Mutex or ACE_RW_Mutex + + typedef ACE_Hash_Multi_Map_Manager<ACE_CString, + ACE_CString, + ACE_Hash<ACE_CString>, + ACE_Equal_To<ACE_CString>, + ACE_RW_Mutex> CIMap; + + typedef CIMap::ITERATOR CIMap_Iterator; + typedef CIMap::ENTRY CIEntry; + typedef CIEntry::VALUE_SET CISet; + typedef CIEntry::VALUE_SET_ITERATOR CISet_Iterator; + + /// A hash map that associates the names of + /// PackageConfigurations with their location + PCMap names_; + + /// a hash map that associates the UUIDs of + /// PackageConfigurations with their location + PCMap uuids_; + + /// a hash map which associates Component Interface + /// UUIDs with their implementations + CIMap types_; + + /// The ORB + CORBA::ORB_var the_orb_; + + /// Will hold the current working directory + char cwd_ [TEMP_LEN]; + + /// Full path for the install directory + ACE_CString install_root_; + + /// Location of the server + ACE_CString HTTP_server_; + + /// Directory where the packages will be stored locally + ACE_CString install_path; +}; + +#endif /* REPOSITORYMANAGER_H_ */ diff --git a/modules/CIAO/DAnCE/RepositoryManager/URL_Parser.cpp b/modules/CIAO/DAnCE/RepositoryManager/URL_Parser.cpp new file mode 100644 index 00000000000..37187ebff61 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/URL_Parser.cpp @@ -0,0 +1,101 @@ +// $Id$ + +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "URL_Parser.h" + +#include "ace/ACE.h" +#include "ace/OS_NS_string.h" + +bool +URL_Parser::parse_args (int argc, ACE_TCHAR *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("rwu:h:p:f:d")); + + bool success = true; + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'd': + this->debug_ = true; + break; + case 'u': + success = parseURL (get_opt.opt_arg ()); + break; + // Usage fallthrough. + default: + success = false; + } + + if (this->hostname_ == 0 || this->filename_ == 0) + { + success = false; + } + + return success; +} + +URL_Parser::URL_Parser (void) + : hostname_ (ACE::strnew ("127.0.0.1")), + port_ (ACE_DEFAULT_HTTP_SERVER_PORT), + filename_ (0), + debug_ (false) +{ +} + +bool URL_Parser::parseURL (char* url) +{ + char* ptr = 0; + bool success = true; + ptr = ACE_OS::strstr (url, "http://"); + if (ptr) + url += ACE_OS::strlen ("http://"); + + if (url[0] == '/') + { + this->filename_ = ACE_OS::strdup (url); + } + else + { + ptr = ACE_OS::strstr (url, ":"); + if (ptr) + this->port_ = ACE_OS::atoi (ptr + 1); + else + ptr = ACE_OS::strstr (url, "/"); + + if(!ptr) + success = false; + else + { + size_t host_len = ptr - url; + ACE::strdelete (this->hostname_); + ACE_NEW_RETURN (this->hostname_, char [host_len + 1], false); + ACE_OS::strncpy (this->hostname_, url, host_len); + this->hostname_ [host_len] = '\0'; + ptr = ACE_OS::strstr (ptr, "/"); + if (ptr) + { + this->filename_ = ACE_OS::strdup(ptr); + } + else + { + success = false; + } + } + } + return success; +} + + +void URL_Parser::Error (void) +{ + ACE_DEBUG ((LM_DEBUG, "./http_client -u http://hostname:port/filename [-d]\n")); +} + +URL_Parser::~URL_Parser() +{ + delete [] this->hostname_; + ACE_OS::free (this->filename_); +} diff --git a/modules/CIAO/DAnCE/RepositoryManager/URL_Parser.h b/modules/CIAO/DAnCE/RepositoryManager/URL_Parser.h new file mode 100644 index 00000000000..0dfef0262ad --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/URL_Parser.h @@ -0,0 +1,66 @@ + +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file URL_Parser.h + * + * $Id$ + * + * Parses a URL into its logical chunks + * + * @author Stoyan Paunov + */ +//============================================================================= + + +#ifndef URL_PARSER_H +#define URL_PARSER_H + +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "ace/Singleton.h" //for ACE_Singleton +#include "ace/Null_Mutex.h" //for ACE_Null_Mutex + +// Forward declaration +class URL_Parser; + +typedef ACE_Singleton <URL_Parser, ACE_Null_Mutex> TheURL_Parser; + +class URL_Parser +{ +public: + + friend class ACE_Singleton <URL_Parser, ACE_Null_Mutex>; + + /// Parses commandline arguments + bool parse_args (int argc, ACE_TCHAR *argv[]); + + /// Return false on failure + bool parseURL (char* url); + + void Error (void); + + /// Hostname to connect to + ACE_TCHAR *hostname_; + + /// Port number to use + u_short port_; + + /// Filename to upload/download + ACE_TCHAR *filename_; + + /// Turns on verbosity + bool debug_; + + /// destructor + ~URL_Parser (void); + +protected: + /// protected constructor, singleton + URL_Parser (void); +}; + + + +#endif /* URL_PARSER_H */ diff --git a/modules/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp b/modules/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp new file mode 100644 index 00000000000..b318af0ad13 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.cpp @@ -0,0 +1,375 @@ + +//=============================================================================== +/** + * @file ZIP_Wrapper.cpp + * + * $Id$ + * + * Purpose: implementing the ZIP_Wrapper class + * + * @author Stoyan Paunov, Vipul Singh + * + */ +//=============================================================================== + +#include "ace/Containers_T.h" //for ACE_Double_Linked_List +#include "ace/Message_Block.h" //for ACE_Message_Block +#include "ace/OS_NS_fcntl.h" //for open +#include "ace/OS_NS_unistd.h" //for close +#include "ace/OS_NS_string.h" //for strncpy +#include "ace/SString.h" //for ACE_CString +#include "ace/OS_NS_sys_stat.h" //for stat +#include "ace/OS_NS_sys_stat.h" //for filesize and mkdir +#include "ace/OS_Memory.h" //for ACE_NEW* macros + +#include <string> +#include "unzip.h" +#define MAXFILENAME (256) +#define CASESENSITIVITY (0) +#define WRITEBUFFERSIZE (8192) + +#include "ZIP_Wrapper.h" + +//ZIP_File_Info constructor +ZIP_File_Info::ZIP_File_Info (char* name, size_t size) + : name_ (name), + size_ (size), + next_ (0), + prev_ (0) +{ +} + +//ZIP_File_Info default constructor +ZIP_File_Info::ZIP_File_Info () + : name_ (""), + size_ (0), + next_ (0), + prev_ (0) +{ +} + + +/// Gets a list of the files in the archive. +int ZIP_Wrapper::file_list_info (char* zip_name, + ACE_Double_Linked_List<ZIP_File_Info> &list) +{ + unzFile uf=0; + char filename_try[MAXFILENAME+16] = ""; + if (zip_name!=0) + { + strncpy(filename_try, zip_name, MAXFILENAME-1); + /* strncpy doesnt append the trailing NULL, if the string is too long. */ + filename_try[ MAXFILENAME ] = '\0'; + /* open the zip file */ + uf = unzOpen(zip_name); + /* if zipfile could not be opened, try appending .zip to name */ + if (uf==0) + { + ACE_OS::strcat(filename_try, ".zip"); + uf = unzOpen(filename_try); + } + } + /* If zipfile could not be opened still, return */ + if (uf==0) + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("There is some problem in opening" + " %s or %s.zip using unzOpen \n"), zip_name, zip_name)); + return 1; + } + unz_global_info gi; + /* get information about all the files in zip file*/ + int err = unzGetGlobalInfo(uf, &gi); + if (err!=UNZ_OK) + ACE_DEBUG((LM_DEBUG, ACE_TEXT("unzGetGlobalInfo failed while trying" + " to get global information about zipfile \n"), err)); + /* gi.number_entry corresponds to the number of directory entries + in the zip file */ + for (uLong i=0;i<gi.number_entry;i++) + { + char filename_inzip[256]; + unz_file_info file_info; + /* get information about the current file in zip file */ + err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, + sizeof(filename_inzip), 0, 0, 0, 0); + if (err!=UNZ_OK) + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("unzGetCurrentFileInfo failed" + " while trying to get information" + " about current file\n"), err)); + break; + } + ZIP_File_Info* next = 0; + ACE_NEW_RETURN (next, ZIP_File_Info (filename_inzip, + sizeof(filename_inzip)), -1); + /* add information about current file to the list */ + list.insert_tail (next); + if ((i+1)<gi.number_entry) + { + err = unzGoToNextFile(uf); + if (err!=UNZ_OK) + { + ACE_DEBUG((LM_DEBUG,ACE_TEXT(" unzGoToNextFile failed" + " while trying to go to next file\n"), err)); + break; + } + } + } + unzCloseCurrentFile(uf); + return gi.number_entry; +} + + +//get file and store it into ACE message block. +bool ZIP_Wrapper::get_file (char* archive_path, char* filename, + ACE_Message_Block &file) +{ + bool return_code = true; + unzFile uf=0; + uf = unzOpen(archive_path); + /* locate the desired file in the zip file and set it as current file*/ + int j=unzLocateFile(uf, filename, 0); + if (j==UNZ_END_OF_LIST_OF_FILE) + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("File not found in zip archive"))); + return false; + } + else if (j==UNZ_OK) + { + int k=unzOpenCurrentFile(uf); + if (k!=UNZ_OK) + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("Error in opening the current" + " file using unzOpenCurrentFile"))); + return false; + } + else + { + int num_read = 0; + ACE_Message_Block* head = &file; + + //read the file into the ACE_Message_Block + do + { + if (head->space () == 0) + { + ACE_Message_Block* next = 0; + ACE_NEW_RETURN (next, ACE_Message_Block (BUFSIZ), false); + head->cont (); + head = head->cont (); + } + num_read = unzReadCurrentFile(archive_path, head->wr_ptr(), + head->space()); + if (num_read > 0) + head->wr_ptr (num_read); + } while (num_read > 0); + if (num_read < 0) + return_code = false; + unzCloseCurrentFile(uf); + unzClose(uf); + return return_code; + } + } + return return_code; +} + + +/// uncompress the zip file +/// The zip file will be uncompressed into a directory +/// with the name of zip archive. +/// the path is assumed to be an existing directory + +bool ZIP_Wrapper::uncompress (char* zip_archive, char* path, bool verbose) +{ + //open the zip archive + unzFile uf=0; + uf = unzOpen(zip_archive); + if (uf==0) + { + ACE_DEBUG((LM_DEBUG,ACE_TEXT("unzOpen failed to open the" + " zipfile\n"))); + return false; + } + //get the name of the archive + ACE_CString arch_dir (path); + arch_dir += "/"; + //get only the name of the archive; remove path info + char* n = ACE_OS::strstr (zip_archive, "/"); + char* zip_name = 0; + while (n != 0) + { + zip_name = ++n; + n = ACE_OS::strstr (n, "/"); + } + arch_dir += zip_name; + //NOTE: Assumes .zip or cpk extension + arch_dir = arch_dir.substring (0, arch_dir.length () - 4); + //create directory with the name of zip archive + ACE_OS::mkdir(arch_dir.c_str()); + //if dir exists -1 is returned and ignored + unz_global_info gi; + int err = unzGetGlobalInfo(uf, &gi); + if (err!=UNZ_OK) + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("unzGetGlobalInfo failed to get global" + " information about zipfile \n"), err)); + return false; + } + err =unzGoToFirstFile(uf); + if (err!=UNZ_OK) + { + ACE_DEBUG((LM_DEBUG,ACE_TEXT("error %d with zipfile in" + " unzGoToFirstFile \n"), err)); + return false; + } + /* read each entry of zip file, create directory structure if it is + a non existing directory whereas if it is a file, write the file + at the proper path in the directory structure */ + for (uLong i=0;i<gi.number_entry;i++) + { + char filename_inzip[256]; + unz_file_info file_info; + err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, + sizeof(filename_inzip), 0, 0, 0, 0); + if (err!=UNZ_OK) + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("unzGetCurrentFileInfo failed" + " while trying to get information" + " about currentfile\n"), err)); + break; + } + int direc = checkdir(filename_inzip); + /* If it is a directory, we create directory structure */ + if (direc==1) + { + makethedir(filename_inzip, arch_dir); + } + /* If it is a file, we read its data and write the uncompressed + data to the file with proper path.*/ + else if (direc==0) + { + handlethefile(filename_inzip, uf, file_info, verbose, arch_dir); + } + if ((i+1)<gi.number_entry) + { + err = unzGoToNextFile(uf); + if (err!=UNZ_OK) + { + ACE_ERROR((LM_ERROR,ACE_TEXT("unzGoToNextFile failed" + " while trying to go to" + " nextfile\n"), err)); + break; + } + } + } + unzClose(uf); + return true; +} + + + +///try to find if it is a directory OR file +int ZIP_Wrapper::checkdir (char* filename_inzip) +{ + int direc = 0; + char* dircheck = ACE_OS::strstr (filename_inzip, "/"); + /* We assume that a directory will have its entry terminating in a / + We also assume that the directory entries in the zip file use + forward slash for both unix and windows */ + while (dircheck != 0) + { + int i = ACE_OS::strcmp(dircheck, "/"); + if (i == 0) + { + direc = 1; + break; + } + ++dircheck; + dircheck = ACE_OS::strstr (dircheck, "/"); + } + return direc; +} + +///Create directory structure if entry in zipfile is a directory +int ZIP_Wrapper::makethedir (char* filename_inzip, ACE_CString arch_dir) +{ +//let's try to create the directory structure for the package + char dir_name [2048]; + char* next = ACE_OS::strstr (filename_inzip, "/"); + while (next != 0) + { + ACE_CString location (arch_dir); + ACE_OS::strncpy (dir_name, filename_inzip, next - filename_inzip + + 1); + + dir_name[next - filename_inzip + 1] = '\0'; + location += "/"; + location += dir_name; + ACE_stat stat; + if (ACE_OS::stat (location.c_str (), &stat) == -1) + ACE_OS::mkdir (location.c_str ()); + next++; + next = ACE_OS::strstr (next, "/"); + } + return 0; +} + +///If entry in zipfile is a file, then read the file and write the +///uncompressed data at the proper filepath. +int ZIP_Wrapper::handlethefile (char* filename_inzip, unzFile uf, + unz_file_info file_info, bool verbose, + ACE_CString arch_dir) +{ + int k = unzOpenCurrentFile(uf); + if (k!=UNZ_OK) + { + ACE_ERROR((LM_ERROR,ACE_TEXT("unzOpenCurrentFile failed in" + " opening the current file"))); + return false; + } + else + { + size_t const file_size = file_info.uncompressed_size; + char* temp = 0; + ACE_NEW_RETURN (temp, char [file_size], false); + ACE_Auto_Basic_Array_Ptr<char> buffer (temp); + //read in the data + unzReadCurrentFile(uf, &(*buffer), file_size); + //close the zip handle + unzCloseCurrentFile(uf); + //create file name + path to open + std::string file_path (arch_dir.c_str ()); + //NOTE: need the c-style char to stop at '\0' + file_path += "/"; + file_path += filename_inzip; + //print out the file to be uncompressed + if (verbose) + { + ACE_OS::write(ACE_STDOUT, file_path.c_str (), + file_path.length () ); + ACE_OS::write(ACE_STDOUT, "\n", 1); + } + // Open a file handle to the local filesystem + ACE_HANDLE handle = ACE_OS::open (file_path.c_str (), + O_CREAT | O_TRUNC | O_WRONLY); + if (handle == ACE_INVALID_HANDLE) + { + unzClose(uf); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[uncompress] file creation error")), + 0); + } + //write the uncompressed data to the file + if (ACE_OS::write (handle, &(*buffer), file_size) == -1) + { + unzClose(uf); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("[uncompress] file write error")), + 0); + } + // Close the file handle + ACE_OS::close (handle); + } + return 0; +} diff --git a/modules/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.h b/modules/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.h new file mode 100644 index 00000000000..918a60f6352 --- /dev/null +++ b/modules/CIAO/DAnCE/RepositoryManager/ZIP_Wrapper.h @@ -0,0 +1,117 @@ + +/* -*- C++ -*- */ + +//======================================================================= +/** + * @file ZIP_Wrapper.h + * + * $Id$ + * + * Purpose: to provide a wrapper around minizip for easy handling of + * ZIP archives. This wrapper can be used as an auxiliary + * class that allows a program to become ZIP-aware + * + * @author Stoyan Paunov, Vipul Singh + * + * + */ +//======================================================================= + +#ifndef _ZIP_WRAPPER_H_ +#define _ZIP_WRAPPER_H_ + +#include "ace/Containers_T.h" //for ACE_Double_Linked_List +#include "ace/Message_Block.h" //for ACE_Message_Block +#include "ace/SString.h" //for ACE_CString +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/OS_NS_fcntl.h" //for open +#include "ace/OS_NS_sys_stat.h" //for filesize and mkdir + +#include "unzip.h" + + +/** + * @class ZIP_File_Info + * + * This class is used as a carrier of information + * about entities residing inside a ZIP archive + */ +class ZIP_File_Info +{ +public: + ACE_CString name_; + size_t size_; + ZIP_File_Info* next_; + ZIP_File_Info* prev_; + + ZIP_File_Info (char* name, size_t size); + ZIP_File_Info (); +}; + +/** + * @class ZIP_Wrappers + * + * This class is the actual workhorse that provides all of + * the necessary functionality + */ +class ZIP_Wrapper +{ +public: + + /// Get file and store it into an ACE_Message_Block. The function + /// averts subdirectory traversal problems. + /// NOTE: Be sure to release the message block even if the function returns + /// false becuase the return value might be due to unsuccessful allocation + + ///archive_path is the zip archive with the path + ///filename is the name of the file to be looked for in the zip archive. + ///the file is stored in ACE message block. + static bool get_file (char* archive_path, char* filename, + ACE_Message_Block &file); + + /// uncompress the zip file + /// The zip file will be uncompressed into a directory with the + ///name of zip archive. + /// The path is assumed to be an existing directory + + ///zip_archive is the arcive to be uncompressed with full path. + ///path is used for creating a directory with the name of zip archive. + static bool uncompress (char* zip_archive, char* path = "", + bool verbose = true); + + /// Get a list of the files in the archive + + ///zip_name is the name of zipfile with fullpath. + ///list stores information about each entry in zip file. + static int file_list_info (char* zip_name, + ACE_Double_Linked_List<ZIP_File_Info> &list); + + ///Check if an entry of a zip file is a file or directory + ///We assume a directoryname terminates with a forward slash + ///Returns 1 for directory while 0 for file. + + ///filename_inzip is an entry in a zipfile + static int checkdir (char* filename_inzip); + + ///Create directory structure if entry in zipfile is a directory + + ///filename_inzip is an entry in a zipfile + ///arch_dir stores the name of the directory to be created + static int makethedir (char* filename_inzip, ACE_CString arch_dir); + + ///If entry in zipfile is a file, then read the file and write + /// the uncompressed data at the proper filepath. + + ///filename_inzip is an entry in a zipfile + ///uf refers to the zip archive + ///file_info is used to get information about current file + ///verbose decides if the details are to be printed or not + ///arch_dir is the name of file with full path where it is to be + ///uncompressed + static int handlethefile (char* filename_inzip, unzFile uf, + unz_file_info file_info, + bool verbose, ACE_CString arch_dir); +}; + +#endif diff --git a/modules/CIAO/DAnCE/StaticConfigurator/README b/modules/CIAO/DAnCE/StaticConfigurator/README new file mode 100644 index 00000000000..e42c1099cfd --- /dev/null +++ b/modules/CIAO/DAnCE/StaticConfigurator/README @@ -0,0 +1,29 @@ +Please see $CIAO_ROOT/docs/static_dance.html for details. + +To run the static version of Hello example, do the following, + +1. Build ACE+TAO+CIAO statically +2. Build $CIAO_ROOT/examples/Hello +3. Generate the static function entrypoints (plan.h) + > cd $CIAO_ROOT/examples/Hello/descriptors + > $CIAO_ROOT/DAnCE/StaticConfigurator/StaticDAnCEParser -p flattened_deploymentplan_without_ns.cdp + > cp plan.h $CIAO_ROOT/DAnCE/StaticConfigurator/ +4. Build the static NodeManager for Hello example + > cd $CIAO_ROOT/DAnCE/StaticConfigurator + > cp StaticDAnCEApp.cpp.tmpl StaticDAnCEApp.cpp + > cp StaticDAnCEApp.mpc.tmpl StaticDAnCEApp.mpc + > $ACE_ROOT/bin/mwc.pl + > make +5. Run the static node managers. Note that the ORBEndpoint values should + correspond to the ones in $CIAO_ROOT/examples/Hello/descriptors/TestNodeManagerMap.dat + > cd $CIAO_ROOT/DAnCE/StaticConfigurator + > ./StaticDAnCEApp -ORBEndpoint iiop://localhost:60001 & + > ./StaticDAnCEApp -ORBEndpoint iiop://localhost:60002 & +6. Do the deployment. This is just the same as the non-static version of DAnCE + except that we have the NodeManagers already running and need not spawn node + managers. To accomplish this, change + $CIAO_ROOT/examples/Hello/descriptors/run_test_without_ns.pl + to *not* run the node manager daemons and do the following. + > cd $CIAO_ROOT/examples/Hello/descriptors + > ./run_test_without_ns.pl + diff --git a/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEApp.cpp.tmpl b/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEApp.cpp.tmpl new file mode 100644 index 00000000000..985173e5720 --- /dev/null +++ b/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEApp.cpp.tmpl @@ -0,0 +1,119 @@ +// $Id$ + +#include "Container_Base.h" +#include "NodeManager/NodeManager_Impl.h" +#include "ace/OS_NS_stdio.h" +#include "ace/streams.h" +#include "ace/Get_Opt.h" +#include "tao/IORTable/IORTable.h" +#include "tao/CDR.h" +#include "plan.h" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + // Initialize the ORB so that CORBA::Any will work + // + CORBA::ORB_var orb = + CORBA::ORB_init (argc, + argv, + ""); + try + { + // Get reference to Root POA. + CORBA::Object_var obj + = orb->resolve_initial_references ("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POA_var poa + = PortableServer::POA::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Activate POA manager + PortableServer::POAManager_var mgr + = poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + mgr->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + int homes_table_size = + sizeof (homes_table)/sizeof(HomeAttributes); + + CIAO::HOMECREATOR_FUNCPTR_MAP home_creator_fptr_map; + CIAO::HOMESERVANTCREATOR_FUNCPTR_MAP homesvnt_creator_fptr_map; + CIAO::Static_Config_EntryPoints_Maps static_config_entrypoints_maps; + static_config_entrypoints_maps.home_creator_funcptr_map_ = &home_creator_fptr_map; + static_config_entrypoints_maps.home_servant_creator_funcptr_map_ = &homesvnt_creator_fptr_map; + + int i=0; + for (i=0; i<homes_table_size; ++i) + { + home_creator_fptr_map.bind (homes_table[i].executor_entrypt_, + homes_table[i].executor_fptr_); + + homesvnt_creator_fptr_map.bind (homes_table[i].servant_entrypt_, + homes_table[i].servant_fptr_); + } + + CIAO::Static_NodeManager_Impl *static_node_manager_impl; + // Create and install the CIAO Daemon servant + + ACE_DEBUG ((LM_DEBUG, "creating static_node_manager\n")); + + static_node_manager_impl = + new CIAO::Static_NodeManager_Impl("NodeManager", + orb.in (), + poa.in (), + "", //exe location + "", //exe options + 0, //spawn delay + &static_config_entrypoints_maps); + + static_node_manager_impl->init (); + + CORBA::Object_var table_object = + orb->resolve_initial_references ("IORTable" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + IORTable::Table_var adapter = + IORTable::Table::_narrow (table_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (adapter.in ())) + ACE_ERROR_RETURN ((LM_ERROR, "Nil IORTable\n"), -1); + + CIAO::NodeManagerDaemon_var manager = + static_node_manager_impl->_this (); + + CORBA::String_var str = + orb->object_to_string (manager.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + adapter->bind ("NodeManager", + str.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Run the main event loop for the ORB. + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + catch (CORBA::Exception& ex) + { + ACE_PRINT_EXCEPTION (ex, "Caught CORBA Exception: "); + return -1; + } + + return 0; +} diff --git a/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEApp.mpc.tmpl b/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEApp.mpc.tmpl new file mode 100644 index 00000000000..4895dd9a045 --- /dev/null +++ b/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEApp.mpc.tmpl @@ -0,0 +1,20 @@ +// -*- MPC -*- +// $Id$ + +project(StaticDAnCEApp): ciao_static_dnc_app { + exename = StaticDAnCEApp + + libs += Hello_Base_DnC_stub + libs += Hello_Base_DnC_svnt + libs += Receiver_DnC_stub + libs += Receiver_DnC_svnt + libs += Receiver_DnC_exec + libs += Sender_DnC_stub + libs += Sender_DnC_svnt + libs += Sender_DnC_exec + + Source_Files { + StaticDAnCEApp.cpp + } +} + diff --git a/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEParser.cpp b/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEParser.cpp new file mode 100644 index 00000000000..caa7e0a0f61 --- /dev/null +++ b/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEParser.cpp @@ -0,0 +1,159 @@ +//============================================================================= +/** + * @file StaticDAnCEParser.cpp + * + * $Id$ + * + * This parser is used in static deployment of CIAO components. This + * parser parses a deployment plan and generates a header file plan.h + * containing information about the home and servant creation + * function entry points. This can be used by a Static_NodeManager to + * instantiate instances of homes and servants just like the regular + * NodeManager. For more details, see + * $CIAO_ROOT/DAnCE/StaticConfigurator/docs/static_dance.html + * + * @author Venkita Subramonian <venkita@cse.wustl.edu> + */ +//============================================================================= + +#include "DAnCE/NodeApplicationManager/ImplementationInfo.h" +#include "ace/OS_NS_stdio.h" +#include "ace/streams.h" +#include "ace/Get_Opt.h" +#include "tao/IORTable/IORTable.h" +#include "tao/CDR.h" +#include "Config_Handlers/XML_File_Intf.h" + +static void +usage (const ACE_TCHAR* program) +{ + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Usage: %s -p <package URI>\n"), + program)); +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + // top level package URL + char* package_url = 0; + + // Initialize the ORB so that CORBA::Any will work + // + CORBA::ORB_var orb = + CORBA::ORB_init (argc, + argv, + ""); + + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:")); + int c; + + while ((c = get_opt ()) != EOF) + { + switch (c) + { + case 'p': + package_url = get_opt.opt_arg (); + break; + + default: + usage(argv[0]); + return -1; + } + } + + if (package_url == 0) { + usage(argv[0]); + return -1; + } + + CIAO::Config_Handlers::XML_File_Intf intf (package_url); + + ::Deployment::DeploymentPlan_var plan = + intf.get_plan (); + + ::Deployment::ComponentPlans dummy; + dummy.length (0); + + CIAO::NodeImplementationInfoHandler handler (plan, dummy); + + Deployment::NodeImplementationInfo_var node_impl_info (handler.node_impl_info ()); + + if (node_impl_info.ptr() == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "DAnCE (%P|%t) StaticParser -" + "Failed to create Node Implementation Infos!\n"), 1); + + } + + Deployment::ContainerImplementationInfos& impl_infos = node_impl_info->impl_infos; + + FILE* fp = ACE_OS::fopen ("plan.h", "w"); + + CORBA::ULong i,j,num_containers,num_components; + num_containers = impl_infos.length (); + for (i = 0; i < num_containers; ++i) + { + num_components = impl_infos[i].impl_infos.length (); + for (j = 0; j < num_components; ++j) + { + ACE_DEBUG ((LM_DEBUG, "The info for installation: \n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", + impl_infos[i].impl_infos[j].component_instance_name.in (), + impl_infos[i].impl_infos[j].executor_dll.in (), + impl_infos[i].impl_infos[j].executor_entrypt.in (), + impl_infos[i].impl_infos[j].servant_dll.in (), + impl_infos[i].impl_infos[j].servant_entrypt.in () )); + ACE_OS::fprintf (fp, + "extern \"C\" ::Components::HomeExecutorBase_ptr %s (void);\n", + impl_infos[i].impl_infos[j].executor_entrypt.in ()); + ACE_OS::fprintf (fp, + "extern \"C\" ::PortableServer::Servant %s \n", + impl_infos[i].impl_infos[j].servant_entrypt.in ()); + ACE_OS::fprintf (fp, + "\t\t(::Components::HomeExecutorBase_ptr p,\n"); + ACE_OS::fprintf (fp, + "\t\t::CIAO::Session_Container *c,\n"); + ACE_OS::fprintf (fp, + "\t\tconst char*\n"); + ACE_OS::fprintf (fp, + "\t\t);\n"); + } + } + + ACE_OS::fprintf (fp, "struct HomeAttributes\n"); + ACE_OS::fprintf (fp, "{\n"); + ACE_OS::fprintf (fp, " char const * component_instance_name_;\n"); + ACE_OS::fprintf (fp, " /// Specify the entrypoint to component executor DLL.\n"); + ACE_OS::fprintf (fp, " char const * executor_entrypt_;\n"); + ACE_OS::fprintf (fp, " ::CIAO::HomeFactory executor_fptr_;\n"); + ACE_OS::fprintf (fp, " /// Specify the entrypoint to component servant DLL.\n"); + ACE_OS::fprintf (fp, " char const * servant_entrypt_;\n"); + ACE_OS::fprintf (fp, " ::CIAO::ServantFactory servant_fptr_;\n"); + ACE_OS::fprintf (fp, "};\n"); + ACE_OS::fprintf (fp, "/// Homes\n"); + ACE_OS::fprintf (fp, "HomeAttributes homes_table[]= \n"); + ACE_OS::fprintf (fp, "{\n"); + + num_containers = impl_infos.length (); + for (i = 0; i < num_containers; ++i) + { + num_components = impl_infos[i].impl_infos.length (); + for (j = 0; j < num_components; ++j) + { + ACE_OS::fprintf (fp, "\t{\"%s\", \"%s\", %s, \"%s\", %s}", + impl_infos[i].impl_infos[j].component_instance_name.in (), + impl_infos[i].impl_infos[j].executor_entrypt.in (), + impl_infos[i].impl_infos[j].executor_entrypt.in (), + impl_infos[i].impl_infos[j].servant_entrypt.in (), + impl_infos[i].impl_infos[j].servant_entrypt.in () ); + if (!(i == num_containers -1 && j == num_components-1)) + ACE_OS::fprintf (fp, ",\n"); + } + } + ACE_OS::fprintf (fp, "};\n\n"); + + ACE_OS::fclose (fp); + + return 0; +} diff --git a/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEParser.mpc b/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEParser.mpc new file mode 100644 index 00000000000..1234b0a03bb --- /dev/null +++ b/modules/CIAO/DAnCE/StaticConfigurator/StaticDAnCEParser.mpc @@ -0,0 +1,10 @@ +// -*- MPC -*- +// $Id$ + +project(StaticDAnCEParser): ciao_component_dnc, taoexe, ciao_config_handlers, ciao_domainapplicationmanager_dnc, iortable, ciao_server_dnc, ciao_nodeapplicationmanager { + exename = StaticDAnCEParser + + Source_Files { + StaticDAnCEParser.cpp + } +} diff --git a/modules/CIAO/DAnCE/TargetManager/CmpClient.cpp b/modules/CIAO/DAnCE/TargetManager/CmpClient.cpp new file mode 100644 index 00000000000..12deaa5ac80 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/CmpClient.cpp @@ -0,0 +1,271 @@ +// $Id$ +/** + * @file CmpClient.cpp + * + * @brief This file contains a client of TargetManager. + * + * It picks up the TM ior from the Targetmanager.ior file + * present in the current directory, and makes the calls on the + * TM to getAllResources and getAvailable resources + */ + +#include "ciao/Deployment_DataC.h" +#include "DAnCE/TargetManager/TargetManagerImplC.h" +#include "ace/streams.h" +#include "Config_Handlers/DnC_Dump.h" + +void write_to_file (::Deployment::Domain domain); + +int main (int argc, char* argv[]) +{ + try { + // First initialize the ORB, that will remove some arguments... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, + "" /* the ORB name, it can be anything! */); + + // There must be at least two arguments, the first is the factory + // name, the rest are the names of the stock symbols we want to + // get quotes for. + if (argc < 2) { + cerr << "Usage: " << argv[0] + << " Factory_IOR ..." << endl; + return 1; + } + + // Use the first argument to create the factory object reference, + // in real applications we use the naming service, but let's do + // the easy part first! + CORBA::Object_var factory_object = + orb->string_to_object (argv[1]); + + // Now downcast the object reference to the appropriate type + CIAO::TargetManagerImpl_var targetCmp = + CIAO::TargetManagerImpl::_narrow (factory_object.in ()); + + // Now get the facet reference from the target Manager Component + ACE_DEBUG((LM_DEBUG, "Making a Call to provide_targetMgr ()\n")); + Deployment::TargetManager_ptr targetI = targetCmp->provide_targetMgr (); + + // Now make calls on the Target Manager facet + + try + { + Deployment::Domain_var domainV = targetI->getAllResources (); + ACE_DEBUG ((LM_DEBUG , "\n\nGetAllResources Returned \n")); + ::Deployment::DnC_Dump::dump (domainV); + } + catch(CORBA::NO_IMPLEMENT &) + { + ACE_DEBUG((LM_DEBUG ,"Error:TargetManager:CORBA::NO_IMPLEMENT thrown\n")); + } + catch(CORBA::Exception &) + { + ACE_DEBUG((LM_DEBUG ,"Error:TargetManager:CORBA Generic Exception \n")); + ACE_DEBUG((LM_DEBUG ,"Error:TargetManager:Exception in TargetManager call\n")); + } + + + // make a call to the commit resources ..... + + + Deployment::DeploymentPlan plan; + + plan.instance.length (2); + + ::Deployment::InstanceDeploymentDescription instance_; + instance_.node = CORBA::string_dup ("foil"); + instance_.deployedResource.length (1); + instance_.deployedResource[0].requirementName = + CORBA::string_dup ("Processor"); + instance_.deployedResource[0].resourceName = + CORBA::string_dup ("CPULoad"); + + instance_.deployedResource[0].property.length (1); + instance_.deployedResource[0].property[0].name = + CORBA::string_dup ("LoadAverage"); + CORBA::Long d = 20; + instance_.deployedResource[0].property[0].value <<= d; + + plan.instance[0] = instance_; + + instance_.node = CORBA::string_dup ("blade30"); + instance_.deployedResource.length (1); + instance_.deployedResource[0].requirementName = + CORBA::string_dup ("Processor"); + instance_.deployedResource[0].resourceName = + CORBA::string_dup ("CPULoad"); + + instance_.deployedResource[0].property.length (1); + instance_.deployedResource[0].property[0].name = + CORBA::string_dup ("LoadAverage"); + d = 50; + + instance_.deployedResource[0].property[0].value <<= d; + + plan.instance[1] = instance_; + + bool resource_available = true; + + try + { + targetI->commitResources(plan); + ACE_DEBUG ((LM_DEBUG , "\n\ncommitResources Returned \n")); + } + catch(CORBA::NO_IMPLEMENT &) + { + cerr << "Error:TargetManager:CORBA::NO_IMPLEMENT thrown" << endl; + } + catch (Deployment::ResourceNotAvailable & e) + { + resource_available = 0; + cout << "TargetManager commitResources ResourceNotAvailable Exception" <<endl; + + ACE_DEBUG ((LM_DEBUG , + "ResourceNotAvailable\n name=[%s]\n elementName=[%s]\n resourceName=[%s]\n \ + resourceType= [%s]\n propertyName=[%s]\n", + e.name.in (), + e.elementName.in (), + e.resourceName.in (), + e.resourceType.in (), + e.propertyName.in ())); + } + catch(CORBA::Exception & ex) + { + cout << "Error:TargetManager:commitResources Exception" <<endl; + cout << "Error:TargetManager:CORBA Generic Exception " << endl; + cerr << "Error:TargetManager:Exception in TargetManager call" << ex << endl; + } + + + // Make a call to release resources , if resource < 0 + try + { + if (!resource_available) + { + targetI->releaseResources(plan); + ACE_DEBUG ((LM_DEBUG , "\n\nreleaseResources Returned \n")); + } + } + catch(CORBA::NO_IMPLEMENT &) + { + cerr << "Error:TargetManager:CORBA::NO_IMPLEMENT thrown" << endl; + } + catch (Deployment::ResourceNotAvailable &) + { + cout << "Error:TargetManager releaseResources ResourceNotAvailable Exception" <<endl; + } + catch(CORBA::Exception & ex) + { + cout << "Error:TargetManager:releaseResources Exception" <<endl; + cout << "Error:TargetManager:CORBA Generic Exception " << endl; + cerr << "Error:TargetManager:Exception in TargetManager call" << ex << endl; + } + + // Here make a call on the TM with update domain and node deletion + + ::Deployment::Domain updated; + updated.node.length (1); + updated.node[0].name = CORBA::string_dup (argv[2]); + + ::CORBA::StringSeq elements; + elements.length (0); + + bool Add = true; + Add = ACE_OS::atoi (argv[3]); + + if (Add) + { + try + { + targetI->updateDomain (elements , updated, ::Deployment::Add); + } + catch(CORBA::NO_IMPLEMENT &) + { + cerr << "Error:TargetManager:CORBA::NO_IMPLEMENT thrown" << endl; + } + catch(CORBA::Exception & ex) + { + cout << "Error:TargetManager:CORBA Generic Exception " << endl; + cerr << "Error:TargetManager:Exception in UpdateDomain call" << ex << endl; + } + } + else + { + try + { + targetI->updateDomain (elements , updated, ::Deployment::Delete); + } + catch(CORBA::NO_IMPLEMENT &) + { + cerr << "Error:TargetManager:CORBA::NO_IMPLEMENT thrown" << endl; + } + catch(CORBA::Exception & ex) + { + cout << "Error:TargetManager:CORBA Generic Exception " << endl; + cerr << "Error:TargetManager:Exception in UpdateDomain call" << ex << endl; + } + } + // Now make a call of getAvailableResources on the TargetManager ... + try + { + Deployment::Domain_var domainV = targetI->getAvailableResources(); + + // here write things to file ... + write_to_file (domainV.in()); + + ACE_DEBUG ((LM_DEBUG , "\n\nGetAvailableResources Returned \n")); + ::Deployment::DnC_Dump::dump (domainV); + } + catch(CORBA::NO_IMPLEMENT &) + { + cerr << "Error:TargetManager:CORBA::NO_IMPLEMENT thrown" << endl; + } + catch(CORBA::Exception & ex) + { + cout << "Error:TargetManager:CORBA Generic Exception " << endl; + cerr << "Error:TargetManager:Exception in TargetManager call" << ex << endl; + } + + // Finally destroy the ORB + orb->destroy (); + } + catch (CORBA::Exception & ex) { + cerr << "Error:TargetManager:CORBA exception raised!" << ex << endl; + } + return 0; +} + +void write_to_file (::Deployment::Domain domain) +{ + for (size_t i = 0;i < domain.node.length ();i++) + { + std::ofstream out (domain.node[i].name.in ()); + + + // write in the node usage ... + for (size_t j = 0;j < domain.node[i].resource.length ();j++) + { + + if (!strcmp (domain.node[i].resource[j].name.in (), "Processor")) + { + CORBA::Double node_cpu; + domain.node[i].resource[j].property[0].value >>= node_cpu; + out << node_cpu << std::endl; + } + if (!strcmp (domain.node[i].resource[j].name.in (), "NA_Monitor")) + { + std::string file_name = "NA_"; + file_name += domain.node[i].name.in (); + std::ofstream na_out (file_name.c_str ()); + CORBA::Double na_node_cpu; + domain.node[i].resource[j].property[0].value >>= na_node_cpu; + na_out << na_node_cpu << std::endl; + na_out.close (); + } + } + + out.close (); + } + +} diff --git a/modules/CIAO/DAnCE/TargetManager/DomainDataManager.cpp b/modules/CIAO/DAnCE/TargetManager/DomainDataManager.cpp new file mode 100644 index 00000000000..da7f59a3b86 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/DomainDataManager.cpp @@ -0,0 +1,738 @@ +// $Id$ +//=============================================================== +/** + * @file DomainDataManager.cpp + * + * @brief Maintains the Domain Information + * + * It contains the entire Domain information.Both the + * initial domain as well as the current available domain. + * + * @author Nilabja Roy nilabjar@dre.vanderbilt.edu + */ +//=============================================================== +#include "DomainDataManager.h" + +#include "Config_Handlers/DD_Handler.h" +#include "Config_Handlers/DnC_Dump.h" +#include "ciao/CIAO_common.h" + +const char * domain_file_name = "Domain.cdd"; + +CIAO::DomainDataManager* CIAO::DomainDataManager::global_data_manager_ = 0; + +CIAO::DomainDataManager * CIAO::DomainDataManager::create (CORBA::ORB_ptr orb, + ::Deployment::TargetManager_ptr target + ) +{ + if (global_data_manager_ == 0) + { + global_data_manager_ = new DomainDataManager (orb , target); + } + return global_data_manager_; +} + + +CIAO::DomainDataManager* +CIAO::DomainDataManager::get_data_manager () +{ + return global_data_manager_; +} + + +void +CIAO::DomainDataManager::delete_data_manger () +{ + if (global_data_manager_) + delete global_data_manager_; +} + + + +int CIAO::DomainDataManager::update_domain ( + const ::CORBA::StringSeq &, + const ::Deployment::Domain & domainSubset, + ::Deployment::DomainUpdateKind update_kind) +{ + // Update the subset of the domain which the above + // parameter corresponds to + + + //check the type of update .. + + switch (update_kind) + { + case ::Deployment::UpdateAll: + case ::Deployment::UpdateAvailable: + break; + case ::Deployment::Add: + add_to_domain (domainSubset); + break; + case ::Deployment::Delete: + delete_from_domain (domainSubset); + break; + default: + break; + } + + int size = current_domain_.node.length (); + + int i; + for (i=0;i < size;i++) + { + if (!strcmp (domainSubset.node[0].name , + current_domain_.node[i].name)) + { + // found a match + // for now overwrite the entire Node info ... + // but later , this has to be changed to overwrite + // only the specific part ... + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "TM::Changed the cpu Value\n")); + } + current_domain_.node[i] = domainSubset.node[0]; + break; // finished job ...break + } + } + + if (i == size) + { + // thus the node is new .. add it to current_domain_ + // later change it ... + current_domain_.node.length (size+1); + current_domain_.node[size]=domainSubset.node[0]; + } + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , + "TM::Inside The update Domain of Manager\n")); + } + return 0; +} + +CIAO::DomainDataManager:: +DomainDataManager (CORBA::ORB_ptr orb, + ::Deployment::TargetManager_ptr target) + : orb_ (CORBA::ORB::_duplicate (orb)), + deployment_config_ (orb_.in()), + target_mgr_ (::Deployment::TargetManager::_duplicate(target)) +{ + // ACE_DEBUG((LM_DEBUG , "Calling DD_HANDLER\n")); + CIAO::Config_Handlers::DD_Handler dd (domain_file_name); + // ACE_DEBUG((LM_DEBUG , "After DD_HANDLER Constructor\n")); + ::Deployment::Domain* dmn = dd.domain_idl (); + // ACE_DEBUG((LM_DEBUG , "After DD_HANDLER domain_idl\n")); + + if (CIAO::debug_level () > 9) + ::Deployment::DnC_Dump::dump (*dmn); + + current_domain_ = *dmn; + initial_domain_ = current_domain_; + + // initialize the provisioning domain + provisioned_data_ = initial_domain_; + + update_node_status (); + + call_all_node_managers (); +} + +::Deployment::Domain* CIAO::DomainDataManager::get_current_domain () +{ + return new ::Deployment::Domain (provisioned_data_); +} + +::Deployment::Domain* CIAO::DomainDataManager::get_initial_domain () +{ + return new ::Deployment::Domain (initial_domain_); +} + +int CIAO::DomainDataManager::readin_domain_data () +{ + // here read in Domain data ... + // + return 0; +} + +int CIAO::DomainDataManager::call_all_node_managers () +{ + if ( this->deployment_config_.init ("NodeDetails.dat") == -1 ) + { + ACE_ERROR ((LM_ERROR, + "TargetM (%P|%t) DomainDataManager.cpp -" + "CIAO::DomainDataManager::call_all_node_managers -" + "ERROR while trying to initialize after reading " + "node details DAT file \n")); + return 0; + } + + CORBA::ULong const length = initial_domain_.node.length (); + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, "Number of nodes in domain.cdd is : %d\n", length)); + } + + for (CORBA::ULong i=0;i < length;i++) + { + + ::Deployment::NodeManager_var node_manager; + + try + { + node_manager = + deployment_config_.get_node_manager + (initial_domain_.node[i].name.in ()); + } + catch (CORBA::Exception&) + { + ACE_ERROR ((LM_ERROR, "DANCE::TM (%P|%t) DomainDataManager.cpp: " + "Error trying to contact NodeManager %s\n", + initial_domain_.node[i].name.in ())); + continue; + } + + + if (!CORBA::is_nil (node_manager.in ())) + { + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, "Trying to contact nodemanager on %s\n", + initial_domain_.node[i].name.in ())); + } + Deployment::Logger_ptr log = + Deployment::Logger::_nil (); + ::Deployment::Domain sub_domain; + sub_domain.UUID = CORBA::string_dup("Node-Level-domain"); + sub_domain.label = CORBA::string_dup("Node-level-domain"); + sub_domain.sharedResource.length(0); + sub_domain.interconnect.length(0); + sub_domain.bridge.length(0); + sub_domain.infoProperty.length(0); + sub_domain.node.length (1); + sub_domain.node[0] = initial_domain_.node[i]; + try + { + node_manager->joinDomain (sub_domain, + target_mgr_.in (), + log); + } + catch (CORBA::Exception& ex) + { + ACE_DEBUG ((LM_DEBUG , "TM::Error in calling Join Domain==\n")); + ex._tao_print_exception ( + "Exception caught in ""DomainDataManager::joinDomain"); + } + } + } + return 0; + +} + +CIAO::Host_NodeManager_seq * CIAO::DomainDataManager::get_node_managers () +{ + ::CIAO::Host_NodeManager_seq* node_mgr_seq = + new ::CIAO::Host_NodeManager_seq (); + node_mgr_seq->length (initial_domain_.node.length ()); + for (unsigned int i=0;i < initial_domain_.node.length ();i++) + { + (*node_mgr_seq)[i].host_ = + CORBA::string_dup (initial_domain_.node[i].name); + ::Deployment::NodeManager_var node_manager = + deployment_config_.get_node_manager (initial_domain_.node[i].name); + // if (node_manager.in () != 0) + { + (*node_mgr_seq)[i].node_mgr_ = ::CIAO::NodeManagerDaemon::_narrow (node_manager.in ()); + } + } + return node_mgr_seq; +} + +CIAO::Host_Infos* CIAO::DomainDataManager::get_cpu_info () +{ + CIAO::Host_Infos* host_info_seq = new CIAO::Host_Infos (); + host_info_seq->length (current_domain_.node.length ()); + + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG , "TM:: The node length is [%d]", + current_domain_.node.length ())); + + for (unsigned int i=0;i < current_domain_.node.length ();i++) + { + (*host_info_seq)[i].hostname = + CORBA::string_dup (current_domain_.node[i].name); + // ACE_DEBUG ((LM_DEBUG , "The resource length is [%d]", + // current_domain_.node[i].resource.length ())); + + for (unsigned int j = 0;j < current_domain_.node[i].resource.length ();j++) + { + if (!strcmp( + current_domain_.node[i].resource[j].name, + "Processor")) + { + current_domain_.node[i].resource[j].property[0].value + >>= (*host_info_seq)[i].cpu_util; + CORBA::Double d; + current_domain_.node[i].resource[j].property[0].value + >>= d; + // ACE_DEBUG ((LM_DEBUG, "TM::The current cpu util is [%f]\n", d)); + } + } + } + + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG , "TM::Returning from get_cpu_info")); + + return host_info_seq; +} + +CORBA::Long CIAO::DomainDataManager::get_pid (ACE_CString cmp) +{ + CORBA::Long pid; + + // This is really ineffiecient this is O(n) ; searching all the nodes + // all the resources for a particular component. + // It needs to be stored in some other data structure + + for (unsigned int i=0;i < current_domain_.node.length ();i++) + { + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG , "TM::The resource length is [%d]", + current_domain_.node[i].resource.length ())); + + for (unsigned int j = 0;j < current_domain_.node[i].resource.length ();j++) + { + // The resource + if (!ACE_OS::strcmp( + current_domain_.node[i].resource[j].name, + "Component") && + ACE_CString (current_domain_.node[i].resource[j].property[0].name) == + cmp) + { + current_domain_.node[i].resource[j].property[0].value + >>= pid; + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG, + "TM::getpid::The current pid is [%d]\n", pid)); + + } + } // resources + }// nodes + + return pid; +} + +void CIAO::DomainDataManager +::commitResources ( + const ::Deployment::DeploymentPlan & plan) +{ + // commit the resources + // parse into the plan and commit resources ... + + // set the action value + current_action_ = commit; + + // temporary created to guard against exceptions + ::Deployment::Domain temp_provisioned_data = + provisioned_data_; + + for (unsigned int i = 0;i < plan.instance.length ();i++) + { + for (unsigned int j = 0;j < temp_provisioned_data.node.length ();j++) + { + if (!strcmp (plan.instance[i].node.in () , + temp_provisioned_data.node[j].name.in ())) + { + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG , + "TM::commitResource::Host name matched\n")); + try { + match_requirement_resource ( + plan.instance[i].deployedResource, + temp_provisioned_data.node[j].resource); + } + catch (::Deployment::ResourceNotAvailable& ex) + { + // catch the exception and add parameters + ex.elementName = + CORBA::string_dup (temp_provisioned_data.node[j].name); + + throw ex; + } + } + } + } + + // here commit the commitresources + provisioned_data_ = temp_provisioned_data; +} + + +void CIAO::DomainDataManager:: +releaseResources ( + const ::Deployment::DeploymentPlan& plan) +{ + // release the resources + + + // set the action value + current_action_ = release; + + for (unsigned int i = 0;i < plan.instance.length ();i++) + { + for (unsigned int j = 0;j < provisioned_data_.node.length ();j++) + { + if (!ACE_OS::strcmp (plan.instance[i].node.in () , + provisioned_data_.node[j].name.in ())) + { + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , + "TM::commitResource::Host name matched\n")); + } + + match_requirement_resource ( + plan.instance[i].deployedResource, + provisioned_data_.node[j].resource); + + } + } + } + +} + + +void CIAO::DomainDataManager:: +match_requirement_resource ( + ::Deployment::InstanceResourceDeploymentDescriptions deployed, + ::Deployment::Resources & available + ) +{ + // here match the deployed to the available + + for (CORBA::ULong i = 0;i < deployed.length ();i++) + { + // for each deployed resource ....search the corresponding + // available resource + for (CORBA::ULong j = 0;j < available.length ();j++) + { + if (!strcmp (deployed[i].requirementName, available[j].name)) + { + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG , + "TM::commitResource::Requirement name matched\n")); + // search for the resourcename in the resourceType + for (CORBA::ULong k = 0;k < available[j].resourceType.length ();k++) + { + if (!strcmp (deployed[i].resourceName, + available[j].resourceType[k])) + { + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG , + "TM::commitResource::Resource name matched\n")); + + try { + match_properties (deployed[i].property, + available[j].property); + } + catch (::Deployment::ResourceNotAvailable& ex) + { + // catch the exception and add parameters + ex.resourceType = + CORBA::string_dup (available[j].resourceType[k]); + ex.resourceName = + CORBA::string_dup (available[j].name); + throw ex; + } + } + } + } + } + } + +} + +void CIAO::DomainDataManager:: +match_properties ( + ::Deployment::Properties deployed, + ::Deployment::SatisfierProperties & available) +{ + for (CORBA::ULong i = 0;i < deployed.length ();i++) + { + for (CORBA::ULong j = 0;j < available.length ();j++) + if (!ACE_OS::strcmp (deployed[i].name , available[j].name)) + { + // check kind here ....and then subtract .... + // accordingly , ..this is complex ... better to write + // some specialised algo + // for now assuming Capacity .... + // and tk_double .... + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG , + "TM::commitResource::Property name matched\n")); + + commit_release_resource (deployed[i] , available[j]); + + } + } +} + +void CIAO::DomainDataManager::commit_release_resource ( + ::Deployment::Property & deployed, + ::Deployment::SatisfierProperty & available) +{ + if (current_action_ == commit) + { + + CORBA::Long required_d; + + if ((deployed.value >>= required_d) == false) + ACE_ERROR ((LM_ERROR, "Failed to extract required amount\n")); + + CORBA::Long available_d; + + if ((available.value >>= available_d) == false) + ACE_ERROR ((LM_ERROR, "failed to extract available amount\n")); + + if (available_d >= required_d) + { + available_d = available_d - required_d; + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG, "TM::The available is [%f]", + available_d)); + + available.value <<= available_d; + } + else + { + ACE_DEBUG ((LM_DEBUG, "Insufficient resources! Available: %d, Required %d\n", + available_d, required_d)); + throw ::Deployment::ResourceNotAvailable ("", + "", + deployed.name.in (), + "", + ""); + } + + + } + else + { + //must be release + // @todo check return value of >>= + CORBA::Long required_d; + deployed.value >>= required_d; + CORBA::Long available_d; + available.value >>= available_d; + + available_d = available_d + required_d; + + // Should we check for bin > 100 ?????? + + if (CIAO::debug_level () > 9) + ACE_DEBUG ((LM_DEBUG, "TM::The available is [%f]", + available_d)); + + available.value <<= available_d; + } +} + +void CIAO::DomainDataManager::stop_monitors () +{ + + CORBA::ULong length = initial_domain_.node.length (); + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, "Number of nodes in domain.cdd is : %d\n", length)); + } + + for (CORBA::ULong i=0;i < length;i++) + { + ::Deployment::NodeManager_var node_manager; + + try + { + node_manager = + deployment_config_.get_node_manager + (initial_domain_.node[i].name.in ()); + } + catch (CORBA::Exception&) + { + ACE_ERROR ((LM_ERROR, "DANCE::TM (%P|%t) DomainDataManager.cpp: " + "Error in get Node Manager from Deployment Config %s\n", + initial_domain_.node[i].name.in ())); + continue; + } + + + if (!CORBA::is_nil (node_manager.in ())) + { + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG, "Trying to contact nodemanager on %s\n", + initial_domain_.node[i].name.in ())); + } + try + { + node_manager->leaveDomain (); + } + catch (CORBA::Exception& ex) + { + ACE_DEBUG ((LM_DEBUG , "TM::Error in calling Leave Domain\n")); + ex._tao_print_exception ( + "Exception caught in ""DomainDataManager::leaveDomain"); + } + } + } + return; + +} + +int CIAO::DomainDataManager::add_to_domain ( + const ::Deployment::Domain& domain) +{ + // here add the domain to the Domain + // right now use only a node + + // got to take care of the fact , that a node can be added , + // while it is still in the domain + + //iterate through the supplied domain + //for each node + // find it in the pristine domain + // and copy it back to the provisioned_domain + + for (CORBA::ULong i = 0;i < domain.node.length ();i++) + { + //find in the pristine domain + ::Deployment::Node a_node; + + if (!this->find_in_initial_domain (domain.node[i].name.in (), + a_node)) + continue; // dont know this node + + //check if already present + if (!this->find_in_provisioned_domain (domain.node[i].name.in (), + a_node)) + { + // add the node to the domain ... + provisioned_data_.node.length (provisioned_data_.node.length () + 1); + provisioned_data_.node[provisioned_data_.node.length () - 1] = + a_node; + } + } + +// ::Deployment::DnC_Dump::dump (this->provisioned_data_); + + ACE_DEBUG ((LM_DEBUG, "TM::Node Up Message Processed\n")); + + return 0; +} + +bool CIAO::DomainDataManager:: +find_in_initial_domain (const char* node_name, + ::Deployment::Node& node) +{ + for (CORBA::ULong i =0; + i < this->initial_domain_.node.length (); + i++) + { + if (ACE_OS::strcmp (node_name, this->initial_domain_.node[i].name.in ()) == 0) + { + node = this->initial_domain_.node[i]; + return true; + } + } + + // not found the node , return a node with an empty name + return false; +} + + +bool CIAO::DomainDataManager:: +find_in_provisioned_domain (const char* node_name, + ::Deployment::Node& node) +{ + for (CORBA::ULong i =0; + i < this->provisioned_data_.node.length (); + i++) + { + if (ACE_OS::strcmp (node_name, this->provisioned_data_.node[i].name.in ()) == 0) + { + node = this->provisioned_data_.node[i]; + return true; + } + } + + // not found the node , return a node with an empty name + return false; +} + +int CIAO::DomainDataManager::delete_from_domain ( + const ::Deployment::Domain& domain) +{ + // validate input + if (domain.node.length () == 0) + return 1; + + if (domain.node.length () > + this->provisioned_data_.node.length ()) + return 0; + + //algo : parse through the provisioned_data + // for each node , find in the deleted domain list + // if not found add it to the updated nodes list + + ::Deployment::Nodes updated_nodes; + bool found = false; + + for (CORBA::ULong j = 0; + j < this->provisioned_data_.node.length (); + j++) + { + found = false; + + for (CORBA::ULong i = 0;i < domain.node.length ();i++) + { + if (strcmp (domain.node[i].name.in (), + this->provisioned_data_.node[j].name.in ()) == 0) + { + found = true; + break; // found the node + } + } + if (found) + continue; + + // not found in the deleted list + + // update the length of the list + updated_nodes.length (updated_nodes.length () + 1); + + // copy the node info + updated_nodes[updated_nodes.length () - 1] = + this->provisioned_data_.node[j]; + + } // for provisioned_data + + // here update the provisioned data + this->provisioned_data_.node = updated_nodes; + + return 1; +} + +int CIAO::DomainDataManager::intimate_planner ( + const ::Deployment::Domain& domain) +{ + // use the connection with the planner and get a reference to the planner + // make a call top the planner + Deployment::Domain d = domain; + return 0; + +} + +bool CIAO::DomainDataManager::update_node_status () +{ + // update the node status here ... + return 0; +} diff --git a/modules/CIAO/DAnCE/TargetManager/DomainDataManager.h b/modules/CIAO/DAnCE/TargetManager/DomainDataManager.h new file mode 100644 index 00000000000..d75e314606d --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/DomainDataManager.h @@ -0,0 +1,290 @@ +// $Id$ +//=============================================================== +/** + * @file DomainDataManager.h + * + * @brief Maintains the Domain Information + * + * It contains the entire Domain information. Both the + * initial domain as well as the current available domain. + * + * @author Nilabja Roy nilabjar@dre.vanderbilt.edu + */ +//=============================================================== +#ifndef DOMAIN_DATA_MGRH +#define DOMAIN_DATA_MGRH + +#include "TargetManagerImplC.h" +#include "DAnCE/DomainApplicationManager/Deployment_Configuration.h" + +/** + * @namespace CIAO + * + * @brief The main CIAO namespace + * + */ +namespace CIAO +{ + /** + * @class DomainDataManager + * + * @brief Responsible for maintaining the Domain Information + * + * It maintains both the Current Domain Information as well + * as the Initial domain at full capacity. + */ + class DomainDataManager + { + + public : + /** + * @brief This function is called by the other classes to update + * current domain data. + * @param elements The string sequence of elements + * being updated + * @param domainSubset The subset of the actual Domain to be updated + * @param updateKind Specifies the update type eg. add, delete, update + * + */ + int update_domain (const ::CORBA::StringSeq & elements, + const ::Deployment::Domain & domainSubset, + ::Deployment::DomainUpdateKind updateKind + ); + /** + * @brief This function is called the Executor code + * to get the Original Domain data. + * @return Domain* The Initial Domain + * + */ + ::Deployment::Domain* get_initial_domain (); + + /** + * @brief This function is called the Executor code + * to get the Current Domain data. + * @return Domain* The Current Domain + */ + ::Deployment::Domain* get_current_domain (); + + + /** + * This function calls the constructor of the + * class Domain Data Manager + * @brief This function is called to create the Datamanager + * @param orb The orb pointer + * @param target The Target Manager Object Reference + * + */ + static DomainDataManager * create (CORBA::ORB_ptr orb, + ::Deployment::TargetManager_ptr target + ); + + /** + * @brief Returns the static pointer to the + * data manager. + * @return DomainDataManager* + * @description The staic get_data_manger function returning + * the data_manager pointer + */ + static DomainDataManager* get_data_manager (); + + /** + * @brief deletes the data manager + */ + static void delete_data_manger (); + + /** + * @brief returns the sequence of node managers + * object reference + */ + CIAO::Host_NodeManager_seq * + get_node_managers (); + + /** + * @brief returns the node specific cpu utilization + * + * @return CIAO::Host_Infos* + */ + + CIAO::Host_Infos* get_cpu_info (); + + /** + * @brief returns the pid of the component id submitted + * @param cmp The component id + * + * @return process id + */ + CORBA::Long get_pid (ACE_CString cmp); + + /** + * @brief commits the resources that are specified + * in the plan. + * @param plan ::Deployment::DeploymentPlan + * @exception ::Deployment::ResourceNotAvailable thrown + * when the resources mentioned in the plan exceeds + * the current resource. + * @exception ::Deployment::PlanError thrown if the plan has any + * error + * + */ + void commitResources ( + const ::Deployment::DeploymentPlan & plan); + + /** + * @brief The function releases the resources held by a plan + * @param plan ::Deployment::DeploymentPlan the plan whose + * resources are to be released + */ + void releaseResources ( + const ::Deployment::DeploymentPlan& plan); + + /** + * The node manager in turn stops the monitor + * @brief The function makes a call on the leaveDomain on the + * NodeManager + */ + void stop_monitors (); + + protected: + + /** + * The constructor made protected so that no one can create + * it. + * @param orb The orb pointer + * @param target The Target Manager Object Reference + */ + DomainDataManager (CORBA::ORB_ptr orb, + ::Deployment::TargetManager_ptr target + ); + + /** + * @brief It will read the initial Domain data from + * XML files. + */ + int readin_domain_data (); + + /** + * @brief Match the deployed resources to the + * available resource + */ + void match_requirement_resource ( + ::Deployment::InstanceResourceDeploymentDescriptions deployed, + ::Deployment::Resources& available + ); + + /** + * @brief Match the properties of a Requirement to the + * properties of available resource + * @param deployed The deployed Properties + * @param available The available Properties + */ + void match_properties ( + ::Deployment::Properties deployed, + ::Deployment::SatisfierProperties& available); + + + /// The different actiona that can take place + enum Action {commit , release}; + + /** + * @brief Either commits or releases the given resource + * based on the current Action set. + * @param deployed ::Deployment::Property is the resource + * to be commited/released + * @param available ::Deployment::SatisfierProperty is the + * available resource from which committed/released. + * @exception ::Deployment::ResourceNotAvailable thrown + * when the deployed resources exceeds + * the available resource. + */ + void commit_release_resource ( ::Deployment::Property & deployed, + ::Deployment::SatisfierProperty & available); + + /** + * @brief This function calls all NM and gives them + * the sub-domain + */ + int call_all_node_managers (); + + /** + * @brief This function add new elements to the + * already existing domain + * + * @param domain Deployment::Domain contians the new + * elements + */ + int add_to_domain (const ::Deployment::Domain& domain); + + /** + * @brief This function deletes elements from the domain + * + * @param domain ::Deployment::Domain contains the new elements + * in the domain + */ + int delete_from_domain (const ::Deployment::Domain& domain); + + /** + * @brief This function intimates the planner about a domain + * change + * + * @param domain ::Deployment::Domain contains the new elements + * in the domain + */ + int intimate_planner (const ::Deployment::Domain& domain); + + /** + * @brief This function finds a new node in the initial_domain + * + * @param node The name of the node which is to be searched + */ + + bool find_in_initial_domain (const char* node_name, + ::Deployment::Node& node); + /** + * @brief This function finds a new node in the proviosiond_domain + * + * @param node The name of the node which is to be searched + */ + bool find_in_provisioned_domain (const char* node_name, + ::Deployment::Node& node); + + /** + * @brief updates the node status by reading it from a file + */ + bool update_node_status (); + + /// The ORB pointer + CORBA::ORB_var orb_; + + /// The Deployment Configuration + CIAO::Deployment_Configuration deployment_config_; + + /// The Initial Domain - contains resources + /// at total capacity + ::Deployment::Domain initial_domain_; + + + /// The Current Domain - contains resources + /// at current capacity + ::Deployment::Domain current_domain_; + + /// The Target Manager Context + ::Deployment::TargetManager_var target_mgr_; + + /** + * The staic data manager pointer implementing + * singleton pattern + */ + static DomainDataManager* global_data_manager_; + + /** + * The static provisioned Domain data + */ + ::Deployment::Domain provisioned_data_; + + /// The current action + Action current_action_; + }; + +} // CIAO + +#endif /* DOMAIN_DATA_MGRH */ diff --git a/modules/CIAO/DAnCE/TargetManager/DomainEvents.idl b/modules/CIAO/DAnCE/TargetManager/DomainEvents.idl new file mode 100644 index 00000000000..4fe089a86a6 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/DomainEvents.idl @@ -0,0 +1,25 @@ +/** + * @file DomainEvents.idl + * @brief Contains Events in the Domain + * + * @author Nilabja R <nilabjar@dre.vanderbilt.edu> + * + * $Id$ + */ + +#ifndef DOMAIN_CHANGE_IDL +#define DOMAIN_CHANGE_IDL + +#include "ciao/Deployment_TargetManager.idl" +#include "ciao/CCM_Events.idl" + +module CIAO +{ + eventtype Domain_Changed_Event + { + public ::Deployment::Domain changes; + public ::Deployment::DomainUpdateKind change_kind; + }; +}; + +#endif diff --git a/modules/CIAO/DAnCE/TargetManager/TM_Client.mpc b/modules/CIAO/DAnCE/TargetManager/TM_Client.mpc new file mode 100644 index 00000000000..0a203ab1476 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TM_Client.mpc @@ -0,0 +1,21 @@ +// $Id$ + +// Client.mpc,v 1.6 2005/02/18 09:07:06 jwillemsen Exp + +project(TMClient): ciao_client_dnc,ciao_deployment_stub, ciao_config_handlers, ciao_events_dnc, ciao_targetmanager_stub { + IDL_Files { + } + + Source_Files { + CmpClient.cpp + } + + Header_Files { + } + + Inline_Files { + } + + Template_Files { + } +} diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManager.cidl b/modules/CIAO/DAnCE/TargetManager/TargetManager.cidl new file mode 100644 index 00000000000..6e880c069e9 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManager.cidl @@ -0,0 +1,27 @@ +// $Id$ + +/* + * @file TargetManager.cidl + * @brief The file contains the TargetManager component + * defination + */ + +#ifndef TARGETMANAGER_CIDL +#define TARGETMANAGER_CIDL + +#include "TargetManagerImpl.idl" + +/* + * @composition TargetManager_i + */ + +composition session TargetManager_i +{ + home executor TargetManagerHome_Exec + { + implements CIAO::TargetManagerHome; + manages TargetManagerImpl_Exec; + }; +}; + +#endif diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManager.mpc b/modules/CIAO/DAnCE/TargetManager/TargetManager.mpc new file mode 100644 index 00000000000..11d1bd518b9 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManager.mpc @@ -0,0 +1,62 @@ +// $Id$ + +project(CIAO_TargetManager_stub): ciao_client_dnc, ciao_deployment_stub, ciao_nodemanager_stub { + sharedname = TargetManager_stub + idlflags += -Wb,stub_export_macro=TARGETMANAGER_STUB_Export \ + -Wb,stub_export_include=TargetManager_stub_export.h \ + -Wb,skel_export_macro=TARGETMANAGER_SVNT_Export \ + -Wb,skel_export_include=TargetManager_svnt_export.h + dynamicflags = TARGETMANAGER_STUB_BUILD_DLL + + IDL_Files { + TargetManagerImpl.idl + TargetManagerExt.idl + DomainEvents.idl + } + + Source_Files { + TargetManagerImplC.cpp + TargetManagerExtC.cpp + DomainEventsC.cpp + } +} + +project(CIAO_TargetManager_svnt) : ciao_servant_dnc, ciao_targetmanager_stub { + sharedname = TargetManager_svnt + + idlflags += -Wb,export_macro=TARGETMANAGER_SVNT_Export \ + -Wb,export_include=TargetManager_svnt_export.h + + dynamicflags = TARGETMANAGER_SVNT_BUILD_DLL + + CIDL_Files { + TargetManager.cidl + } + + IDL_Files { + TargetManagerE.idl + } + + Source_Files { + TargetManagerEC.cpp + TargetManagerImplS.cpp + TargetManagerExtS.cpp + TargetManager_svnt.cpp + DomainEventsS.cpp + } +} + + +project(CIAO_TargetManager_exec) : ciao_component_dnc, ciao_config_handlers, ciao_domainapplicationmanager_dnc, ciao_targetmanager_svnt { + sharedname = TargetManager_exec + + dynamicflags = TARGETMANAGER_EXEC_BUILD_DLL + + Source_Files { + DomainDataManager.cpp + TargetManager_exec.cpp + } + + IDL_Files { + } +} diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManagerExt.idl b/modules/CIAO/DAnCE/TargetManager/TargetManagerExt.idl new file mode 100644 index 00000000000..025d8188e39 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManagerExt.idl @@ -0,0 +1,79 @@ +// $Id$ + +/** + * @file TargetManagerExt.idl + * + * @brief The Extensions to the TM interface for ARMS demo + * + * @author Nilabja R <nilabjar@dre.vanderbilt.edu> + * @author Nishanth Shankaran <nshankar@dre.vanderbilt.edu> + * + * This file declares a interface which will be implemented as + * a facet by the TargetManager component + */ + +/** + * @module CIAO + * + * @brief The CIAO module + */ + +#include "DAnCE/Interfaces/NodeManagerDaemon.idl" + +module CIAO +{ + /** + * @struct Cpu_Info + * @brief Consists of individual host-cpu info + */ + struct Host_Info + { + string hostname; + double cpu_util; + }; + + /// The sequence of CPU infos + typedef sequence<Host_Info> Host_Infos; + + /** + * @struct Component_Cpu_Util + * @brief Contains a component CPU Util + */ + struct Component_Info + { + string component_name; + double cpu_util; + }; + + /// The sequence of component cpu utilization + typedef sequence <Component_Info> Component_Infos; + + + /** + * @struct Host_NodeManager + * @brief Contains the node manager to host reference + */ + struct Host_NodeManager + { + string host_; + ::CIAO::NodeManagerDaemon node_mgr_; + }; + + /// Sequence of NodeManager. + typedef sequence <Host_NodeManager> Host_NodeManager_seq; + + /** + * @interface TargetManagerExt + * @brief The Target Manager Extension + * + * Contains the interface used by the RACE + * controller. + */ + interface TargetManagerExt + { + long get_pid (in string component_uuid); + Host_Infos get_host_cpu (); + Component_Infos get_component_cpu (); + Host_NodeManager_seq get_all_node_managers (); + }; +}; diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManagerImpl.idl b/modules/CIAO/DAnCE/TargetManager/TargetManagerImpl.idl new file mode 100644 index 00000000000..705a3146a75 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManagerImpl.idl @@ -0,0 +1,39 @@ +// $Id$ + +/** + * @file TargetManagerImpl.idl + * @brief TargetManager interface defintion + * + * @author Nilabja R <nilabjar@dre.vanderbilt.edu> + */ + +#ifndef TARGETMGR_IDL +#define TARGETMGR_IDL + +#include "ciao/Components.idl" +#include "ciao/Deployment_Target_Data.idl" +#include "TargetManagerExt.idl" +#include "DomainEvents.idl" + +/** + * @module CIAO + * + * @brief TargetManagenr interface defintion + * + */ +module CIAO +{ + component TargetManagerImpl + { + provides ::Deployment::TargetManager targetMgr; + provides CIAO::TargetManagerExt target_manager_ext; + + publishes Domain_Changed_Event changes; + }; + + home TargetManagerHome manages TargetManagerImpl + { + }; +}; + +#endif diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManager_exec.cpp b/modules/CIAO/DAnCE/TargetManager/TargetManager_exec.cpp new file mode 100644 index 00000000000..a39446e7273 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManager_exec.cpp @@ -0,0 +1,395 @@ +// $Id$ +//=============================================================== +/** + * @file TargetManager_exec.cpp + * + * @brief TargetManager Executor code + * + * @author Nilabja Roy nilabjar@dre.vanderbilt.edu + */ +//=============================================================== +#include "TargetManager_exec.h" +#include "ciao/CIAO_common.h" +#include <orbsvcs/CosNamingC.h> +#include "Config_Handlers/DD_Handler.h" +#include "Config_Handlers/DnC_Dump.h" + +#include "DomainEventsC.h" + +namespace CIDL_TargetManager_i +{ + //================================================================== + // Facet Executor Implementation Class: TargetManager_exec_i + //================================================================== + + TargetManager_exec_i:: + TargetManager_exec_i (TargetManagerImpl_exec_i* exec , + CORBA::ORB_ptr orb, + TargetManagerImpl_Context *context + ) + : _exec (exec), + orb_ (CORBA::ORB::_duplicate (orb)), + context_ (context) + { + // The DomainDataManager created here ... + + // get its own obj ref , then call + + ACE_DEBUG ((LM_DEBUG, "TM_Exec: getting ccm object\n")); + CORBA::Object_var object = context_->get_CCM_object (); + ACE_DEBUG ((LM_DEBUG, "TM_Exec: narrowing target_impl\n")); + CIAO::TargetManagerImpl_var target_impl = + CIAO::TargetManagerImpl::_narrow (object.in ()); + ACE_DEBUG ((LM_DEBUG, "TM_Exec: provide target manager\n")); + ::Deployment::TargetManager_var target = + target_impl->provide_targetMgr (); + // dataManager_.reset (new CIAO::DomainDataManager (orb, target.in ())); + ACE_DEBUG ((LM_DEBUG, "TM_Exec: creating domain data manager\n")); + CIAO::DomainDataManager::create (orb, target.in()); + ACE_DEBUG ((LM_DEBUG, "TM_Exec: DDD created!\n")); + } + + TargetManager_exec_i::~TargetManager_exec_i (void) + { + } + + // Operations from ::Deployment::TargetManager + + ::Deployment::Domain * + TargetManager_exec_i::getAllResources () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + return CIAO::DomainDataManager:: + get_data_manager ()->get_initial_domain (); + } + + ::Deployment::Domain * + TargetManager_exec_i::getAvailableResources () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + return CIAO::DomainDataManager:: + get_data_manager ()->get_current_domain (); + } + + void + TargetManager_exec_i::commitResources ( + const ::Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Deployment::ResourceNotAvailable, + ::Deployment::PlanError)) + { + return CIAO::DomainDataManager:: + get_data_manager ()->commitResources (plan); + } + + void + TargetManager_exec_i::releaseResources ( + const ::Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + return CIAO::DomainDataManager:: + get_data_manager ()->releaseResources (plan); + } + + void + TargetManager_exec_i::updateDomain ( + const ::CORBA::StringSeq & elements , + const ::Deployment::Domain & domainSubset , + ::Deployment::DomainUpdateKind updateKind) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + // Your code here. + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , ".. Update Domain called ...\n")); + } + + CIAO::DomainDataManager:: + get_data_manager ()->update_domain ( + elements, + domainSubset, + updateKind + ); + + // here tell the planner about the changes + + // first get the node names which have failed ... + // assuming nodes to only fail , for now + + if (updateKind == ::Deployment::Delete || + updateKind == ::Deployment::Add) + { + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "TM::Creating the changed event\n")); + } + + CIAO::Domain_Changed_Event_var changed_event = + new OBV_CIAO::Domain_Changed_Event (); + + ::Deployment::Domain_var temp_domain = + new ::Deployment::Domain (domainSubset); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "TM::After getting the current domain\n")); + } + + changed_event->changes (temp_domain); + changed_event->change_kind (updateKind); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "TM::Sending the event to the Planner_Manager\n")); + } + + context_->push_changes (changed_event); + + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "TM::After Sending the event to the Planner_Manager\n")); + } + } + + } + + //================================================================== + // Facet Executor Implementation Class: TargetManagerExt_exec_i + // required for RACE + //================================================================== + + TargetManagerExt_exec_i::TargetManagerExt_exec_i (void) + { + } + + TargetManagerExt_exec_i::~TargetManagerExt_exec_i (void) + { + } + + // Operations from ::CIAO::TargetManagerExt + + ::CORBA::Long + TargetManagerExt_exec_i::get_pid ( + const char * component_uuid) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + // Your code here. + ACE_DEBUG ((LM_DEBUG, "Get PID :: Skeleton Impl")); + return CIAO::DomainDataManager:: + get_data_manager ()->get_pid (component_uuid); + } + + ::CIAO::Host_Infos * + TargetManagerExt_exec_i::get_host_cpu () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + // Your code here. + ACE_DEBUG ((LM_DEBUG, "Get host cpu :: Skeleton Impl entering\n")); + return CIAO::DomainDataManager:: + get_data_manager ()->get_cpu_info (); + } + + ::CIAO::Component_Infos * + TargetManagerExt_exec_i::get_component_cpu () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + // Your code here. + ACE_DEBUG ((LM_DEBUG, "Get component cpu :: Skeleton Impl")); + + // todo + + return 0; + } + + ::CIAO::Host_NodeManager_seq * + TargetManagerExt_exec_i::get_all_node_managers + () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + return CIAO::DomainDataManager:: + get_data_manager ()->get_node_managers (); + } + + //================================================================== + // Component Executor Implementation Class: TargetManagerImpl_exec_i + //================================================================== + + TargetManagerImpl_exec_i::TargetManagerImpl_exec_i (void) + : exec_object_ (0) + { + } + + TargetManagerImpl_exec_i::~TargetManagerImpl_exec_i (void) + { + } + + // Supported or inherited operations. + + // Attribute operations. + + // Port operations. + + ::Deployment::CCM_TargetManager_ptr + TargetManagerImpl_exec_i::get_targetMgr () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + // Your code here. + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "Calling TM constructor")); + } + + if (CORBA::is_nil (this->exec_ext_object_.in ())) + { + this->exec_object_ = new TargetManager_exec_i(this, + context_->_ciao_the_Container()->the_ORB(), + context_ + ); + } + + return ::Deployment::CCM_TargetManager::_duplicate (this->exec_object_.in ()); + } + + ::CIAO::CCM_TargetManagerExt_ptr TargetManagerImpl_exec_i + ::get_target_manager_ext ( + ) ACE_THROW_SPEC ((CORBA::SystemException)) + { + if (CORBA::is_nil (this->exec_ext_object_.in ())) + { + this->exec_ext_object_ = new TargetManagerExt_exec_i(); + } + + return ::CIAO::CCM_TargetManagerExt::_duplicate (this->exec_ext_object_.in ()); + } + + // Operations from Components::SessionComponent + + void + TargetManagerImpl_exec_i::set_session_context ( + ::Components::SessionContext_ptr ctx) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)) + { + this->context_ = + TargetManagerImpl_Context::_narrow ( + ctx); + + if (this->context_ == 0) + { + throw CORBA::INTERNAL (); + } + } + + void + TargetManagerImpl_exec_i::ciao_preactivate () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)) + { + // Your code here. + } + + void + TargetManagerImpl_exec_i::ciao_postactivate () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)) + { + // Your code here. + } + + + void + TargetManagerImpl_exec_i::ccm_activate () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)) + { + // Your code here. + if (CIAO::debug_level () > 9) + { + ACE_DEBUG ((LM_DEBUG , "Inside CCM_ACTIVATE\n")); + } + this->get_targetMgr (); + } + + void + TargetManagerImpl_exec_i::ccm_passivate () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)) + { + // Your code here. + } + + void + TargetManagerImpl_exec_i::ccm_remove () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)) + { + // Your code here. + ACE_DEBUG ((LM_DEBUG , "TM::ccm_remove , calling LeaveDomain\n")); + + //CIAO::DomainDataManager::get_data_manager ()->stop_monitors (); + + ACE_DEBUG ((LM_DEBUG , "TM::ccm_remove , After calling LeaveDomain\n")); + return; + } + + + //================================================================== + // Home Executor Implementation Class: TargetManagerHome_exec_i + //================================================================== + + TargetManagerHome_exec_i::TargetManagerHome_exec_i (void) + { + } + + TargetManagerHome_exec_i::~TargetManagerHome_exec_i (void) + { + } + + // Supported or inherited operations. + + // Home operations. + + // Factory and finder operations. + + // Attribute operations. + + // Implicit operations. + + ::Components::EnterpriseComponent_ptr + TargetManagerHome_exec_i::create () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)) + { + ::Components::EnterpriseComponent_ptr retval = + ::Components::EnterpriseComponent::_nil (); + + ACE_NEW_THROW_EX ( + retval, + TargetManagerImpl_exec_i, + CORBA::NO_MEMORY ()); + + return retval; + } + + extern "C" TARGETMANAGER_EXEC_Export ::Components::HomeExecutorBase_ptr + create_CIAO_TargetManagerHome_Impl (void) + { + ::Components::HomeExecutorBase_ptr retval = + ::Components::HomeExecutorBase::_nil (); + + ACE_NEW_RETURN ( + retval, + TargetManagerHome_exec_i, + ::Components::HomeExecutorBase::_nil ()); + + return retval; + } +} diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManager_exec.h b/modules/CIAO/DAnCE/TargetManager/TargetManager_exec.h new file mode 100644 index 00000000000..fe419bdab8b --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManager_exec.h @@ -0,0 +1,218 @@ +// $Id$ +//=============================================================== +/** + * @file TargetManager_exec.h + * + * @brief TargetManager Executor code + * + * @author Nilabja Roy nilabjar@dre.vanderbilt.edu + */ +//=============================================================== + +#ifndef CIAO_TARGETMANAGER_EXEC_H +#define CIAO_TARGETMANAGER_EXEC_H + +#include /**/ "ace/pre.h" + +#include "TargetManager_svnt.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "TargetManager_exec_export.h" +#include "tao/LocalObject.h" +#include "DomainDataManager.h" + +namespace CIDL_TargetManager_i +{ + class TargetManager_exec_i; + + class TARGETMANAGER_EXEC_Export TargetManagerImpl_exec_i + : public virtual TargetManagerImpl_Exec, + public virtual TAO_Local_RefCounted_Object + { + public: + TargetManagerImpl_exec_i (void); + virtual ~TargetManagerImpl_exec_i (void); + + // Supported or inherited operations. + + // Attribute operations. + + // Port operations. + + virtual ::Deployment::CCM_TargetManager_ptr + get_targetMgr () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::CIAO::CCM_TargetManagerExt_ptr + get_target_manager_ext ( + ) + ACE_THROW_SPEC ((::CORBA::SystemException)); + + // Operations from Components::SessionComponent + + virtual void + set_session_context ( + ::Components::SessionContext_ptr ctx) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)); + + virtual void + ciao_preactivate () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)); + + virtual void + ciao_postactivate () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)); + + virtual void + ccm_activate () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)); + + virtual void + ccm_passivate () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)); + + virtual void + ccm_remove () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)); + + protected: + /// The service context pointer + TargetManagerImpl_Context *context_; + + /// The exec Object + ::Deployment::CCM_TargetManager_var exec_object_; + + ::CIAO::CCM_TargetManagerExt_var exec_ext_object_; + }; + + class TARGETMANAGER_EXEC_Export TargetManagerExt_exec_i + : public virtual ::CIAO::CCM_TargetManagerExt, + public virtual TAO_Local_RefCounted_Object + { + public: + TargetManagerExt_exec_i (void); + virtual ~TargetManagerExt_exec_i (void); + + // Operations from ::CIAO::TargetManagerExt + + virtual ::CORBA::Long + get_pid ( + const char * component_uuid) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::CIAO::Host_Infos * + get_host_cpu () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::CIAO::Component_Infos * + get_component_cpu () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::CIAO::Host_NodeManager_seq * + get_all_node_managers () + ACE_THROW_SPEC ((CORBA::SystemException)); + }; + + class TARGETMANAGER_EXEC_Export TargetManager_exec_i + : public virtual ::Deployment::CCM_TargetManager, + public virtual TAO_Local_RefCounted_Object + { + public: + TargetManager_exec_i (TargetManagerImpl_exec_i* exec, + CORBA::ORB_ptr orb, + TargetManagerImpl_Context *context + ); + virtual ~TargetManager_exec_i (void); + + // Operations from ::Deployment::TargetManager + + virtual ::Deployment::Domain * + getAllResources () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::Deployment::Domain * + getAvailableResources () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + commitResources ( + const ::Deployment::DeploymentPlan & plan) + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Deployment::ResourceNotAvailable, + ::Deployment::PlanError)); + + virtual void + releaseResources ( + const ::Deployment::DeploymentPlan & argname) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + updateDomain ( + const ::CORBA::StringSeq & elements, + const ::Deployment::Domain & domainSubset, + ::Deployment::DomainUpdateKind updateKind) + ACE_THROW_SPEC ((CORBA::SystemException)); + + private: + TargetManagerImpl_exec_i * _exec; + + ///The pointer to the Domain Manager + auto_ptr<CIAO::DomainDataManager> dataManager_; + + /// The CORBA ORB ... + CORBA::ORB_var orb_; + + /// The context object ... + TargetManagerImpl_Context *context_; + }; + + + + class TARGETMANAGER_EXEC_Export TargetManagerHome_exec_i + : public virtual TargetManagerHome_Exec, + public virtual TAO_Local_RefCounted_Object + { + public: + TargetManagerHome_exec_i (void); + virtual ~TargetManagerHome_exec_i (void); + + // Supported or inherited operations. + + // Home operations. + + // Factory and finder operations. + + // Attribute operations. + + // Implicit operations. + + virtual ::Components::EnterpriseComponent_ptr + create () + ACE_THROW_SPEC (( + ::CORBA::SystemException, + ::Components::CCMException)); + }; + + extern "C" TARGETMANAGER_EXEC_Export ::Components::HomeExecutorBase_ptr + create_CIAO_TargetManagerHome_Impl (void); +} + +#include /**/ "ace/post.h" + +#endif /* CIAO_TARGETMANAGER_EXEC_H */ diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManager_exec_export.h b/modules/CIAO/DAnCE/TargetManager/TargetManager_exec_export.h new file mode 100644 index 00000000000..690e5b6136e --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManager_exec_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl TARGETMANAGER_EXEC +// ------------------------------ +#ifndef TARGETMANAGER_EXEC_EXPORT_H +#define TARGETMANAGER_EXEC_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (TARGETMANAGER_EXEC_HAS_DLL) +# define TARGETMANAGER_EXEC_HAS_DLL 1 +#endif /* ! TARGETMANAGER_EXEC_HAS_DLL */ + +#if defined (TARGETMANAGER_EXEC_HAS_DLL) && (TARGETMANAGER_EXEC_HAS_DLL == 1) +# if defined (TARGETMANAGER_EXEC_BUILD_DLL) +# define TARGETMANAGER_EXEC_Export ACE_Proper_Export_Flag +# define TARGETMANAGER_EXEC_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TARGETMANAGER_EXEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TARGETMANAGER_EXEC_BUILD_DLL */ +# define TARGETMANAGER_EXEC_Export ACE_Proper_Import_Flag +# define TARGETMANAGER_EXEC_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TARGETMANAGER_EXEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TARGETMANAGER_EXEC_BUILD_DLL */ +#else /* TARGETMANAGER_EXEC_HAS_DLL == 1 */ +# define TARGETMANAGER_EXEC_Export +# define TARGETMANAGER_EXEC_SINGLETON_DECLARATION(T) +# define TARGETMANAGER_EXEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TARGETMANAGER_EXEC_HAS_DLL == 1 */ + +// Set TARGETMANAGER_EXEC_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TARGETMANAGER_EXEC_NTRACE) +# if (ACE_NTRACE == 1) +# define TARGETMANAGER_EXEC_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TARGETMANAGER_EXEC_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TARGETMANAGER_EXEC_NTRACE */ + +#if (TARGETMANAGER_EXEC_NTRACE == 1) +# define TARGETMANAGER_EXEC_TRACE(X) +#else /* (TARGETMANAGER_EXEC_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TARGETMANAGER_EXEC_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TARGETMANAGER_EXEC_NTRACE == 1) */ + +#endif /* TARGETMANAGER_EXEC_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManager_stub_export.h b/modules/CIAO/DAnCE/TargetManager/TargetManager_stub_export.h new file mode 100644 index 00000000000..d362f4f4ac8 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManager_stub_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl TARGETMANAGER_STUB +// ------------------------------ +#ifndef TARGETMANAGER_STUB_EXPORT_H +#define TARGETMANAGER_STUB_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (TARGETMANAGER_STUB_HAS_DLL) +# define TARGETMANAGER_STUB_HAS_DLL 1 +#endif /* ! TARGETMANAGER_STUB_HAS_DLL */ + +#if defined (TARGETMANAGER_STUB_HAS_DLL) && (TARGETMANAGER_STUB_HAS_DLL == 1) +# if defined (TARGETMANAGER_STUB_BUILD_DLL) +# define TARGETMANAGER_STUB_Export ACE_Proper_Export_Flag +# define TARGETMANAGER_STUB_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TARGETMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TARGETMANAGER_STUB_BUILD_DLL */ +# define TARGETMANAGER_STUB_Export ACE_Proper_Import_Flag +# define TARGETMANAGER_STUB_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TARGETMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TARGETMANAGER_STUB_BUILD_DLL */ +#else /* TARGETMANAGER_STUB_HAS_DLL == 1 */ +# define TARGETMANAGER_STUB_Export +# define TARGETMANAGER_STUB_SINGLETON_DECLARATION(T) +# define TARGETMANAGER_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TARGETMANAGER_STUB_HAS_DLL == 1 */ + +// Set TARGETMANAGER_STUB_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TARGETMANAGER_STUB_NTRACE) +# if (ACE_NTRACE == 1) +# define TARGETMANAGER_STUB_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TARGETMANAGER_STUB_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TARGETMANAGER_STUB_NTRACE */ + +#if (TARGETMANAGER_STUB_NTRACE == 1) +# define TARGETMANAGER_STUB_TRACE(X) +#else /* (TARGETMANAGER_STUB_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TARGETMANAGER_STUB_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TARGETMANAGER_STUB_NTRACE == 1) */ + +#endif /* TARGETMANAGER_STUB_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/TargetManager/TargetManager_svnt_export.h b/modules/CIAO/DAnCE/TargetManager/TargetManager_svnt_export.h new file mode 100644 index 00000000000..f57ce799949 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/TargetManager_svnt_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl TARGETMANAGER_SVNT +// ------------------------------ +#ifndef TARGETMANAGER_SVNT_EXPORT_H +#define TARGETMANAGER_SVNT_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (TARGETMANAGER_SVNT_HAS_DLL) +# define TARGETMANAGER_SVNT_HAS_DLL 1 +#endif /* ! TARGETMANAGER_SVNT_HAS_DLL */ + +#if defined (TARGETMANAGER_SVNT_HAS_DLL) && (TARGETMANAGER_SVNT_HAS_DLL == 1) +# if defined (TARGETMANAGER_SVNT_BUILD_DLL) +# define TARGETMANAGER_SVNT_Export ACE_Proper_Export_Flag +# define TARGETMANAGER_SVNT_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TARGETMANAGER_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TARGETMANAGER_SVNT_BUILD_DLL */ +# define TARGETMANAGER_SVNT_Export ACE_Proper_Import_Flag +# define TARGETMANAGER_SVNT_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TARGETMANAGER_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TARGETMANAGER_SVNT_BUILD_DLL */ +#else /* TARGETMANAGER_SVNT_HAS_DLL == 1 */ +# define TARGETMANAGER_SVNT_Export +# define TARGETMANAGER_SVNT_SINGLETON_DECLARATION(T) +# define TARGETMANAGER_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TARGETMANAGER_SVNT_HAS_DLL == 1 */ + +// Set TARGETMANAGER_SVNT_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TARGETMANAGER_SVNT_NTRACE) +# if (ACE_NTRACE == 1) +# define TARGETMANAGER_SVNT_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TARGETMANAGER_SVNT_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TARGETMANAGER_SVNT_NTRACE */ + +#if (TARGETMANAGER_SVNT_NTRACE == 1) +# define TARGETMANAGER_SVNT_TRACE(X) +#else /* (TARGETMANAGER_SVNT_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TARGETMANAGER_SVNT_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TARGETMANAGER_SVNT_NTRACE == 1) */ + +#endif /* TARGETMANAGER_SVNT_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/TargetManager/descriptors/Domain.cdd b/modules/CIAO/DAnCE/TargetManager/descriptors/Domain.cdd new file mode 100644 index 00000000000..fe21a4b48f5 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/descriptors/Domain.cdd @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<Deployment:domain + xmlns:Deployment="http://www.omg.org/Deployment" + xmlns:xmi="http://www.omg.org/XMI" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.omg.org/Deployment Deployment.xsd"> + +<UUID>effd4bd0-6db0-4c50-9bb7-db9decebae1c</UUID> +<label>Hello Domain</label> + + +<node> + <name>TargetManagerNode_1</name> + <label>Sender's Node</label> + <resource> + <name>Processor</name> + <resourceType>CPULoad</resourceType> + <property> + <name>LoadAverage</name> + <kind>Quantity</kind> + <dynamic>true</dynamic> + <value> + <type> + <kind>tk_long</kind> + </type> + <value><long>99</long></value> + </value> + </property> + </resource> +</node> +<node> + <name>TargetManagerNode_2</name> + <label>Receiver's Node</label> + <resource> + <name>Processor</name> + <resourceType>CPULoad</resourceType> + <property> + <name>LoadAverage</name> + <kind>Quantity</kind> + <dynamic>true</dynamic> + <value> + <type> + <kind>tk_long</kind> + </type> + <value><long>99</long></value> + </value> + </property> + </resource> +</node> + + +<interconnect> + <name>NoBridgeInterConnect</name> + <connect> + <name>Receiver</name> + <resource> + <name>Processor</name> + <resourceType>CPULoad</resourceType> + <property> + <name>LoadAverage</name> + <kind>Quantity</kind> + <dynamic>true</dynamic> + <value> + <type> + <kind>tk_long</kind> + </type> + <value><long>99</long></value> + </value> + </property> + </resource> + </connect> +</interconnect> + + +<bridge> + <name>NoBridge</name> + <connect> + <name>NoBridgeInterConnect</name> + <connect> + <name>Receiver</name> + <resource> + <name>Processor</name> + <resourceType>CPULoad</resourceType> + <property> + <name>LoadAverage</name> + <kind>Quantity</kind> + <dynamic>true</dynamic> + <value> + <type> + <kind>tk_long</kind> + </type> + <value><long>99</long></value> + </value> + </property> + </resource> + </connect> + </connect> +</bridge> + + +</Deployment:domain> diff --git a/modules/CIAO/DAnCE/TargetManager/descriptors/NodeDetails.dat b/modules/CIAO/DAnCE/TargetManager/descriptors/NodeDetails.dat new file mode 100644 index 00000000000..0ca8bfefd8b --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/descriptors/NodeDetails.dat @@ -0,0 +1,2 @@ +TargetManagerNode_1 corbaloc:iiop:localhost:40000/NodeManager +TargetManagerNode_2 corbaloc:iiop:localhost:30000/NodeManager diff --git a/modules/CIAO/DAnCE/TargetManager/descriptors/NodeManagerMap.dat b/modules/CIAO/DAnCE/TargetManager/descriptors/NodeManagerMap.dat new file mode 100644 index 00000000000..0ca8bfefd8b --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/descriptors/NodeManagerMap.dat @@ -0,0 +1,2 @@ +TargetManagerNode_1 corbaloc:iiop:localhost:40000/NodeManager +TargetManagerNode_2 corbaloc:iiop:localhost:30000/NodeManager diff --git a/modules/CIAO/DAnCE/TargetManager/descriptors/flattened_deploymentplan.cdp b/modules/CIAO/DAnCE/TargetManager/descriptors/flattened_deploymentplan.cdp new file mode 100644 index 00000000000..fae71c39fa1 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/descriptors/flattened_deploymentplan.cdp @@ -0,0 +1,92 @@ +<Deployment:deploymentPlan + xmlns:Deployment="http://www.omg.org/Deployment" + xmlns:xmi="http://www.omg.org/XMI" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.omg.org/Deployment Modified_Deployment.xsd"> + + <label>Hello-DeploymentPlan</label> + <!-- Could be ZERO --> + <realizes> + <label>BasicSP-realizes-cid</label> + <UUID>c0965470-7b83-11d9-9669-0800200c9a66</UUID> + <specificType><!-- @@ What does here? --></specificType> + <supportedType>IDL:BasicSP/EC:1.0</supportedType> + <port> + <name>read_message</name> + <specificType>IDL:Hello/ReadMessage:1.0</specificType> + <supportedType>IDL:Hello/ReadMessage:1.0</supportedType> + <provider>false></provider> + <exclusiveProvider>false</exclusiveProvider> + <exclusiveUser>true</exclusiveUser> + <optional>false</optional> + <kind>SimplexReceptacle</kind> + </port> + </realizes> + + <implementation id="TargetManager-mdd"> + <name>TargetManager-mdd</name> + <source><!-- @@ Don't know what goes here --></source> + <artifact>TargetManager_exec</artifact> + <artifact>TargetManager_svnt</artifact> + <!-- + <execParameter></execParameter> + <deployRequirement></deployRequirement> + --> + </implementation> + + <instance id="TargetManager-idd"> + <name>TargetManager-idd</name> + <node>TargetManagerNode_1</node> + <source><!-- @@ What goes here --></source> + <implementation>TargetManager-mdd</implementation> + <configProperty> + <name>ComponentIOR</name> + <value> + <type> + <kind>tk_string</kind> + </type> + <value> + <string>TargetManager.ior</string> + </value> + </value> + </configProperty> + </instance> + + <!-- @@ Runtime library name must match exactly in "location" tag --> + + <artifact id="TargetManager_exec"> + <name>TargetManager_exec</name> + <source><!-- @@ Not sure about this--></source> + <node><!-- blank --></node> + <location>TargetManager_exec</location> + <execParameter> + <name>entryPoint</name> + <value> + <type> + <kind>tk_string</kind> + </type> + <value> + <string>create_CIAO_TargetManagerHome_Impl</string> + </value> + </value> + </execParameter> + </artifact> + + <artifact id="TargetManager_svnt"> + <name>TargetManager_svnt</name> + <source><!-- @@ Not sure --></source> + <node><!-- blank --></node> + <location>TargetManager_svnt</location> + <execParameter> + <name>entryPoint</name> + <value> + <type> + <kind>tk_string</kind> + </type> + <value> + <string>create_CIAO_TargetManagerHome_Servant</string> + </value> + </value> + </execParameter> + </artifact> +</Deployment:deploymentPlan> diff --git a/modules/CIAO/DAnCE/TargetManager/descriptors/run_test_TargetManager.pl b/modules/CIAO/DAnCE/TargetManager/descriptors/run_test_TargetManager.pl new file mode 100644 index 00000000000..a98401ef296 --- /dev/null +++ b/modules/CIAO/DAnCE/TargetManager/descriptors/run_test_TargetManager.pl @@ -0,0 +1,160 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{'ACE_ROOT'}/bin"; +use PerlACE::Run_Test; +$CIAO_ROOT = "$ENV{'CIAO_ROOT'}"; +$DAnCE = "$ENV{'CIAO_ROOT'}/DAnCE"; + +$daemons_running = 0; +$em_running = 0; +$daemons = 2; +@ports = ( 40000, 30000 ); +@iorfiles = ( "NodeApp1.ior", "NodeApp2.ior" ); +$status = 0; +$dat_file = "NodeDetails.dat"; +$cdp_file = "flattened_DeploymentPlan.cdp"; + +$E = 0; +$EM = 0; + +# Delete if there are any .ior files. +sub delete_ior_files { + for ($i = 0; $i < $daemons; ++$i) { + unlink $iorfiles[$i]; + } + unlink PerlACE::LocalFile ("EM.ior"); + unlink PerlACE::LocalFile ("TargetManager.ior"); + unlink PerlACE::LocalFile ("DAM.ior"); +} + +sub kill_node_daemons { + for ($i = 0; $i < $daemons; ++$i) { + $Daemons[$i]->Kill (); $Daemons[$i]->TimedWait (1); + } +} + +sub kill_open_processes { + if ($daemons_running == 1) { + kill_node_daemons (); + } + + if ($em_running == 1) { + $EM->Kill (); + $EM->TimedWait (1); + } +} + +sub run_node_daemons { + for ($i = 0; $i < $daemons; ++$i) + { + $iorfile = $iorfiles[$i]; + $port = $ports[$i]; + + $iiop = "iiop://localhost:$port"; + $node_app = "$DAnCE/NodeApplication/NodeApplication"; + + $d_cmd = "$DAnCE/NodeManager/NodeManager"; + $d_param = "-ORBEndpoint $iiop -s $node_app -o $iorfile"; + + $Daemons[$i] = new PerlACE::Process ($d_cmd, $d_param); + $result = $Daemons[$i]->Spawn (); + push(@processes, $Daemons[$i]); + + if (PerlACE::waitforfile_timed ($iorfile, + $PerlACE::wait_interval_for_process_creation) == -1) { + print STDERR + "ERROR: The ior file of node daemon $i could not be found\n"; + for (; $i > 0; --$i) { + $Daemons[$i]->Kill (); $Daemons[$i]->TimedWait (1); + } + return -1; + } + } + $daemons_running = 1; + return 0; +} + +delete_ior_files (); + +# Invoke node daemons. +print "Invoking node daemons\n"; +$status = run_node_daemons (); + +if ($status != 0) { + print STDERR "ERROR: Unable to execute the node daemons\n"; + exit 1; +} + +$ns_running = 1; + +# Invoke execution manager. +print "Invoking execution manager\n"; +$EM = new PerlACE::Process ("$DAnCE/ExecutionManager/Execution_Manager", + "-o EM.ior -i $dat_file"); +$EM->Spawn (); + +if (PerlACE::waitforfile_timed ("EM.ior", + $PerlACE::wait_interval_for_process_creation) == -1) { + print STDERR + "ERROR: The ior file of execution manager could not be found\n"; + kill_open_processes (); + exit 1; +} + +$em_running = 1; + +# Invoke executor - start the application -. +print "Invoking executor - start the application -\n"; +$E = + new PerlACE::Process ("$DAnCE/Plan_Launcher/plan_launcher", + "-p flattened_deploymentplan.cdp -k file://EM.ior -o DAM.ior"); + +$E->SpawnWaitKill (5000); + +if (PerlACE::waitforfile_timed ( + "TargetManager.ior", + $PerlACE::wait_interval_for_process_creation) == -1) { + print STDERR "ERROR: The ior file of receiver could not be found\n"; + kill_open_processes (); + exit 1; +} + +print "Waiting for 15 secs then invoking client ===\n"; +sleep (15); + +print "Making 5 such calls \n"; + +$call_num = 5; + +for ($i = 0; $i < $call_num; ++$i) +{ + print "Invoking the client\n"; + $tmclient = new PerlACE::Process ("../CmpClient", "file://TargetManager.ior"); + $result = $tmclient->SpawnWaitKill (3000); + + if ($result != 0) { + print STDERR "ERROR: The client returned $result\n"; + $status = 1; + } + sleep (15); +} + +# Invoke executor - stop the application -. +print "Invoking executor - stop the application -\n"; +$E = + new PerlACE::Process ("$DAnCE/Plan_Launcher/plan_launcher", + "-k file://EM.ior -i file://DAM.ior"); +$E->SpawnWaitKill (3000); + +print "Executor returned.\n"; +print "Shutting down rest of the processes.\n"; + +delete_ior_files (); +kill_open_processes (); + +exit $status; diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest.mpc b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest.mpc new file mode 100644 index 00000000000..2cc04a9a18a --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest.mpc @@ -0,0 +1,163 @@ +// $Id$ + +project(NodeAppTest_RoundTrip_stub): ciao_client_dnc { + sharedname = NodeAppTest_RoundTrip_stub + after += CIAO_DnC_Server + + idlflags += -Wb,stub_export_macro=NODEAPPTEST_ROUNDTRIP_STUB_Export \ + -Wb,stub_export_include=RoundTrip_stub_export.h \ + -Wb,skel_export_macro=NODEAPPTEST_ROUNDTRIP_SVNT_Export \ + -Wb,skel_export_include=RoundTrip_svnt_export.h + dynamicflags = NODEAPPTEST_ROUNDTRIP_STUB_BUILD_DLL + + IDL_Files { + NodeAppTest_RoundTrip.idl + } + + Source_Files { + NodeAppTest_RoundTripC.cpp + } + + Header_Files { + NodeAppTest_RoundTripC.h + } + + Inline_Files { + NodeAppTest_RoundTripC.inl + } +} + +project(NodeAppTest_RoundTrip_svnt) : ciao_servant_dnc { + after += NodeAppTest_RoundTrip_stub + sharedname = NodeAppTest_RoundTrip_svnt + + libs += NodeAppTest_RoundTrip_stub + idlflags += -Wb,export_macro=NODEAPPTEST_ROUNDTRIP_SVNT_Export \ + -Wb,export_include=RoundTrip_svnt_export.h + dynamicflags = NODEAPPTEST_ROUNDTRIP_SVNT_BUILD_DLL + + CIDL_Files { + NodeAppTest_RoundTrip.cidl + } + + IDL_Files { + NodeAppTest_RoundTripE.idl + } + + Source_Files { + NodeAppTest_RoundTripEC.cpp + NodeAppTest_RoundTripS.cpp + NodeAppTest_RoundTrip_svnt.cpp + } + + Header_Files { + NodeAppTest_RoundTripEC.h + NodeAppTest_RoundTripS.h + NodeAppTest_RoundTrip_svnt.h + } + + Inline_Files { + NodeAppTest_RoundTripEC.inl + NodeAppTest_RoundTripS.inl + } +} + +project(NodeAppTest_RoundTrip_exec) : ciao_component_dnc, ciao_events_dnc, ciao_server_dnc { + after += NodeAppTest_RoundTrip_stub NodeAppTest_RoundTrip_svnt + + sharedname = NodeAppTest_RoundTrip_exec + libs += NodeAppTest_RoundTrip_stub NodeAppTest_RoundTrip_svnt + idlflags += -Wb,export_macro=NODEAPPTEST_ROUNDTRIP_EXEC_Export \ + -Wb,export_include=RoundTrip_exec_export.h + dynamicflags = NODEAPPTEST_ROUNDTRIP_EXEC_BUILD_DLL + + IDL_Files { + } + + Source_Files { + RoundTrip_exec.cpp + } + + Header_Files { + RoundTrip_exec.h + } + + Inline_Files { + } +} + +project (NodeAppTest_client_simple) : ciao_deployment_stub { + after += NodeAppTest_RoundTrip_stub + libs += NodeAppTest_RoundTrip_stub + exename += client_simple + + IDL_Files { + } + + Source_Files { + NodeApp_test_client_simple.cpp + } + + Header_Files { + } + + Inline_Files { + } +} + +project (NodeAppTest_client) : ciao_deployment_stub { + after += NodeAppTest_RoundTrip_stub + libs += NodeAppTest_RoundTrip_stub + exename += client + + IDL_Files { + } + + Source_Files { + NodeApp_test_client.cpp + } + + Header_Files { + } + + Inline_Files { + } +} + +project (NodeAppTest_client_ex) : ciao_deployment_stub { + after += NodeAppTest_RoundTrip_stub + libs += NodeAppTest_RoundTrip_stub + exename += client_ex + + IDL_Files { + } + + Source_Files { + NodeApp_test_client_ex.cpp + } + + Header_Files { + } + + Inline_Files { + } +} + +project (NodeAppTest_client_dynamic) : ciao_deployment_stub { + after += NodeAppTest_RoundTrip_stub + libs += NodeAppTest_RoundTrip_stub + exename += client_dynamic + + IDL_Files { + } + + Source_Files { + NodeApp_test_client_dynamic.cpp + } + + Header_Files { + } + + Inline_Files { + } +} diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest_RoundTrip.cidl b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest_RoundTrip.cidl new file mode 100644 index 00000000000..3063a673d5a --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest_RoundTrip.cidl @@ -0,0 +1,19 @@ +// $Id$ + +#ifndef NODEAPPTEST_ROUNDTRIP_CIDL +#define NODEAPPTEST_ROUNDTRIP_CIDL + +#include "NodeAppTest_RoundTrip.idl" + +composition session RoundTrip_Impl +{ + + home executor RoundTripHome_Exec + { + implements NodeAppTest::NodeAppTest_RoundTripHome; + manages RoundTrip_Exec; + }; + +}; + +#endif /* NODEAPPTEST_ROUNDTRIP_CIDL */ diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest_RoundTrip.idl b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest_RoundTrip.idl new file mode 100644 index 00000000000..ca7397916b8 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeAppTest_RoundTrip.idl @@ -0,0 +1,34 @@ +// $Id$ + +//============================================================================= +/** + * @file NodeAppTest_RoundTrip.idl + * + * Definition of the Component that provides the LatencyTest interface + * + */ +//============================================================================= +#ifndef NODEAPP_ROUNDTRIP_IDL +#define NODEAPP_ROUNDTRIP_IDL + +#include <Components.idl> + +module NodeAppTest +{ + interface LatencyTest + { + long cube_long (in long param); + }; + + component NodeAppTest_RoundTrip supports LatencyTest + { + provides LatencyTest facet_1; + provides LatencyTest facet_2; + }; + + home NodeAppTest_RoundTripHome manages NodeAppTest_RoundTrip + { + }; + +}; +#endif /* NODEAPP_ROUNDTRIP_IDL */ diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client.cpp b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client.cpp new file mode 100644 index 00000000000..d1ff9b8f67e --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client.cpp @@ -0,0 +1,254 @@ +// $Id$ + +// This test tries to install a set of components in 2 different containers, which +// is hosted in the same NodeApplication. + +#include "Deployment_NodeApplicationC.h" +#include "Client_init.h" +#include "NodeAppTest_RoundTripC.h" +#include "ace/Get_Opt.h" +#include <sstream> +#include <vector> +#include <stdlib.h> +#include "assert.h" + +const char *ior = "file://test.ior"; +int comp_number = 4; +int counter = 0; + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:n:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case 'n': + comp_number = ACE_OS::atoi (get_opts.opt_arg ()); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s \n" + "-k <NodeApplication ior> \n" + "-n <The number of component instances> \n" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + std::vector<NodeAppTest::NodeAppTest_RoundTrip_var> comp_list; + //std::vector<NodeAppTest::NodeAppTest_RoundTrip_var>::const_iterator iter; + + try + { + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::ULong comp_num (comp_number); + ACE_DEBUG ((LM_DEBUG, "CompNum: %d\n",comp_num)); + + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, ""); + + CIAO::Client_init (orb.in ()); + + CORBA::Object_var tmp = + orb->string_to_object(ior); + + Deployment::NodeApplication_var node_app = + Deployment::NodeApplication::_narrow (tmp.in ()); + + if (CORBA::is_nil (node_app.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil nodeapplication reference <%s>\n", ior), + 1); + } + + // This is what we will send out of the ContainerImplmentationInfo for the + // first container + + Deployment::ContainerImplementationInfo container_info_1; + CORBA::ULong length_1 = comp_num/2; + container_info_1.impl_infos.length (CORBA::ULong (length_1)); + + CORBA::ULong i; + for (i = 0; i < length_1; ++i) + { + Deployment::ComponentImplementationInfo info; + + std::stringstream tmp; + tmp << "NodeAppTest_RoundTrip:" << counter; + counter = counter + 1; + + // Add the names and entry points of each of the DLLs + info.component_instance_name = + CORBA::string_dup (tmp.str ().c_str ()); + info.executor_dll = CORBA::string_dup ("NodeAppTest_RoundTrip_exec"); + info.executor_entrypt = + CORBA::string_dup ("createRoundTripHome_Impl"); + info.servant_dll = + CORBA::string_dup ("NodeAppTest_RoundTrip_svnt"); + info.servant_entrypt = + CORBA::string_dup ( + "create_NodeAppTest_NodeAppTest_RoundTripHome_Servant" + ); + + //Now add the info into the infos + container_info_1.impl_infos[i] = info; + } + + // For debug purpose. + for (i = 0; i < comp_num/2; ++i) + { + std::stringstream tmp; + tmp << "NodeAppTest_RoundTrip:" << i; + + // Add the names and entry points of each of the DLLs + ACE_DEBUG ((LM_DEBUG, + "The info I will send out: \n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", + container_info_1.impl_infos[i].component_instance_name.in (), + container_info_1.impl_infos[i].executor_dll.in (), + container_info_1.impl_infos[i].executor_entrypt.in (), + container_info_1.impl_infos[i].servant_dll.in (), + container_info_1.impl_infos[i].servant_entrypt.in () )); + } + + // This is what we will send out of the ContainerImplmentationInfo for the + // first container + + Deployment::ContainerImplementationInfo container_info_2; + CORBA::ULong length_2 = comp_num - comp_num/2; + container_info_2.impl_infos.length (CORBA::ULong (length_2)); + + for (i = 0; i < length_2; ++i) + { + Deployment::ComponentImplementationInfo info; + + std::stringstream tmp; + tmp << "NodeAppTest_RoundTrip:" << counter; + counter = counter + 1; + + // Add the names and entry points of each of the DLLs + info.component_instance_name = + CORBA::string_dup (tmp.str ().c_str ()); + info.executor_dll = CORBA::string_dup ("NodeAppTest_RoundTrip_exec"); + info.executor_entrypt = + CORBA::string_dup ("createRoundTripHome_Impl"); + info.servant_dll = + CORBA::string_dup ("NodeAppTest_RoundTrip_svnt"); + info.servant_entrypt = + CORBA::string_dup ( + "create_NodeAppTest_NodeAppTest_RoundTripHome_Servant" + ); + + //Now add the info into the infos + container_info_2.impl_infos[i] = info; + } + + // For debug purpose. + for (i = 0; i < length_2; ++i) + { + std::stringstream tmp; + tmp << "NodeAppTest_RoundTrip:" << i; + + // Add the names and entry points of each of the DLLs + ACE_DEBUG ((LM_DEBUG, + "The info I will send out: \n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", + container_info_2.impl_infos[i].component_instance_name.in (), + container_info_2.impl_infos[i].executor_dll.in (), + container_info_2.impl_infos[i].executor_entrypt.in (), + container_info_2.impl_infos[i].servant_dll.in (), + container_info_2.impl_infos[i].servant_entrypt.in () )); + } + + // container_info.container_config is not set for now + + ACE_DEBUG ((LM_DEBUG, "Try installing Homes and Components\n")); + + // Create a NodeImplementationInfo sequence + Deployment::NodeImplementationInfo node_info; + node_info.impl_infos.length (2); + node_info.impl_infos[0] = container_info_1; + node_info.impl_infos[1] = container_info_2; + + // Install test component and its home on NodeApplication + Deployment::ComponentInfos_var comp_info = + node_app->install (node_info); + + // store the component refs + for (i = 0; i < comp_num; ++i) + { + comp_list.push_back (NodeAppTest::NodeAppTest_RoundTrip::_narrow + (comp_info[i].component_ref.in ())); + + if (CORBA::is_nil (comp_list[i].in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil RoundTripHome reference: %s \n", + comp_info[i].component_instance_name.in ()), + 1); + } + } + + ACE_DEBUG ((LM_DEBUG, "Installation finished successfully.\n")); + + // Before we can start we have to start. + node_app->start (); + + // Invoke Operation on the components + ACE_DEBUG ((LM_DEBUG, "Try cube_long operation on the Interface \n")); + + for (i = 0; i < comp_num; ++i) + { + + CORBA::Long input = i; + + CORBA::Long output = + (comp_list[i])->cube_long (input); + + if (input*input*input == output) + { + ACE_DEBUG ((LM_DEBUG, + "Return values matched!! on Component: %d \n", + i)); + } + else + { + ACE_DEBUG ((LM_DEBUG, + "Return values did not match: on Component: %d \n", + i)); + ACE_OS::exit (1); + } + } + + ACE_DEBUG ((LM_DEBUG, "Try removing everything\n")); + node_app->remove (); + + ACE_DEBUG ((LM_DEBUG, "Homes and components removed successfully\n")); + + orb->destroy (); + + ACE_DEBUG ((LM_DEBUG, "Test success!!\n")); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + return 1; + } + + return 0; +} diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_dynamic.cpp b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_dynamic.cpp new file mode 100644 index 00000000000..0969c9ec055 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_dynamic.cpp @@ -0,0 +1,155 @@ +// $Id$ + +#include "Deployment_NodeApplicationC.h" +#include "Client_init.h" +#include "NodeAppTest_RoundTripC.h" +#include "ace/Get_Opt.h" +#include "assert.h" + +const char *ior = "file://test.ior"; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s \n" + "-k <ComponentServer ior> \n" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, ""); + + if (parse_args (argc, argv) != 0) + return 1; + + CIAO::Client_init (orb.in ()); + + CORBA::Object_var tmp = + orb->string_to_object(ior); + + Deployment::NodeApplication_var node_app = + Deployment::NodeApplication::_narrow(tmp.in ()); + + if (CORBA::is_nil (node_app.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil nodeapplication reference <%s>\n", + ior), + 1); + } + + + ACE_DEBUG ((LM_DEBUG, "Try installing Home and Component\n")); + + Deployment::ComponentImplementationInfo info; + + // Add the names and entry points of each of the DLLs + info.component_instance_name = + CORBA::string_dup ("NodeAppTest_RoundTrip"); + info.executor_dll = + CORBA::string_dup ("NodeAppTest_RoundTrip_exec"); + info.executor_entrypt = + CORBA::string_dup ("createRoundTripHome_Impl"); + info.servant_dll = + CORBA::string_dup ("NodeAppTest_RoundTrip_svnt"); + info.servant_entrypt = + CORBA::string_dup ( + "create_NodeAppTest_NodeAppTest_RoundTripHome_Servant" + ); + + // Create a ContainerImplementationInfo sequence + Deployment::ContainerImplementationInfo container_info; + container_info.impl_infos.length (1); + container_info.impl_infos[0] = info; + + // Create a NodeImplementationInfo sequence + Deployment::NodeImplementationInfo node_info; + node_info.impl_infos.length (1); + node_info.impl_infos[0] = container_info; + + // Install test component and its home on NodeApplication + Deployment::ComponentInfos_var comp_info = + node_app->install (node_info); + + assert (comp_info->length () == 1); //return 1 component objeref + + const CORBA::ULong i = 0; + Components::CCMObject_var objref = (comp_info[i]).component_ref; + + NodeAppTest::NodeAppTest_RoundTrip_var roundtrip_var = + NodeAppTest::NodeAppTest_RoundTrip::_narrow (objref.in ()); + + if (CORBA::is_nil (roundtrip_var.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil RoundTrip reference\n"), + 1); + } + + // Invoke Operation on the Interface + ACE_DEBUG ((LM_DEBUG, "Try cube_long operation on the Interface \n")); + CORBA::Long input = 1L; + CORBA::Long output = + roundtrip_var->cube_long (input); + + if (input == output) + ACE_DEBUG ((LM_DEBUG, "Retrun values matched!!\n")); + else + { + ACE_DEBUG ((LM_DEBUG, "Return values did not match: failure\n")); + ACE_OS::exit (1); + } + + // Install another set of components + ACE_DEBUG ((LM_DEBUG, "Try installing another component dynamically\n")); + + // Modifying the component instance name since it must be unique + (node_info.impl_infos[0]).impl_infos[0].component_instance_name = + CORBA::string_dup ("NodeAppTest_RoundTrip_2"); + Deployment::ComponentInfos_var comp_info_new = + node_app->install (node_info); + + assert (comp_info_new->length () == 1); //return 1 component objeref + + ACE_DEBUG ((LM_DEBUG, "Try removing the second component and its home\n")); + node_app->remove_component ("NodeAppTest_RoundTrip"); + ACE_DEBUG ((LM_DEBUG, "Component and Home removed successfully\n")); + + ACE_DEBUG ((LM_DEBUG, "=====Try removing all remaining components and homes\n")); + node_app->remove (); + ACE_DEBUG ((LM_DEBUG, "=====Components and Homes removed successfully\n")); + + orb->destroy (); + ACE_DEBUG ((LM_DEBUG, "=====Test success!!\n")); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + return 1; + } + + return 0; +} diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_ex.cpp b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_ex.cpp new file mode 100644 index 00000000000..484e854113d --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_ex.cpp @@ -0,0 +1,169 @@ +// $Id$ + +#include "ciao/Deployment_NodeApplicationC.h" +#include "ciao/Client_init.h" +#include "NodeAppTest_RoundTripC.h" +#include "ace/Get_Opt.h" +#include "assert.h" + +const char *ior = "file://test.ior"; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s \n" + "-k <NodeApplication ior> \n" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, ""); + + if (parse_args (argc, argv) != 0) + return 1; + + CIAO::Client_init (orb.in ()); + + CORBA::Object_var tmp = + orb->string_to_object(ior); + + Deployment::NodeApplication_var node_app = + Deployment::NodeApplication::_narrow(tmp.in ()); + + if (CORBA::is_nil (node_app.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil NodeApplication reference <%s>\n", + ior), + 1); + } + + + ACE_DEBUG ((LM_DEBUG, "Try installing Home and Component\n")); + + Deployment::ComponentImplementationInfo info; + + // Add the names and entry points of each of the DLLs + info.component_instance_name = + CORBA::string_dup ("NodeAppTest_RoundTrip"); + info.executor_dll = + CORBA::string_dup ("NodeAppTest_RoundTrip_exec"); + info.executor_entrypt = + CORBA::string_dup ("createRoundTripHome_Impl"); + info.servant_dll = + CORBA::string_dup ("NodeAppTest_RoundTrip_svnt"); + info.servant_entrypt = + CORBA::string_dup ( + "create_NodeAppTest_NodeAppTest_RoundTripHome_Servant" + ); + + // Create a ContainerImplementationInfo sequence + Deployment::ContainerImplementationInfo container_info; + container_info.impl_infos.length (1); + container_info.impl_infos[0] = info; + + // Create a NodeImplementationInfo sequence + Deployment::NodeImplementationInfo node_info; + node_info.impl_infos.length (1); + node_info.impl_infos[0] = container_info; + + // Install test component and its home on NodeApplication + Deployment::ComponentInfos_var comp_info = + node_app->install (node_info); + + assert (comp_info->length () == 1); //return 1 component objeref + + CORBA::ULong i = 0; + Components::CCMObject_var objref = (comp_info[i]).component_ref; + + NodeAppTest::NodeAppTest_RoundTrip_var roundtrip_var = + NodeAppTest::NodeAppTest_RoundTrip::_narrow (objref.in ()); + + if (CORBA::is_nil (roundtrip_var.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil RoundTrip reference\n"), + 1); + } + + // initialize the component + roundtrip_var->ciao_postactivate (); + + //get the provided facets info. + Components::FacetDescriptions_var facets_info = + roundtrip_var->get_all_facets () ; + + if ( facets_info->length () != 2 ) + { + ACE_DEBUG((LM_DEBUG, "Didn't get 2 facet back! but only %d\n", + facets_info->length ())); + return 1; + } + + // Invoke Operation on the Interface + ACE_DEBUG ((LM_DEBUG, "Try cube_long operation on the Interface \n")); + + for (i = 0; i < 2; ++i ) + { + NodeAppTest::LatencyTest_var latency_var + = NodeAppTest::LatencyTest::_narrow ( (facets_info[i]->facet_ref ())); + ACE_DEBUG((LM_DEBUG, "Calling on facet %s\n", (facets_info[i]->name ()))); + + + if ( CORBA::is_nil (latency_var.in ()) ) + { + ACE_DEBUG((LM_DEBUG, "get nil latency ref for facet%d\n", i)); + return 1; + } + + CORBA::Long input = 1L; + CORBA::Long output = + latency_var->cube_long (input); + + if (input == output) + ACE_DEBUG ((LM_DEBUG, "Retrun values matched!!\n")); + else + { + ACE_DEBUG ((LM_DEBUG, "Return values did not match: failure\n")); + ACE_OS::exit (1); + } + } + + ACE_DEBUG ((LM_DEBUG, "Try removing test component and its home\n")); + node_app->remove (); + ACE_DEBUG ((LM_DEBUG, "Component and Home removed successfully\n")); + + orb->destroy (); + ACE_DEBUG ((LM_DEBUG, "Test success!!\n")); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + return 1; + } + + return 0; +} diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_simple.cpp b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_simple.cpp new file mode 100644 index 00000000000..d239a8db5c5 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/NodeApp_test_client_simple.cpp @@ -0,0 +1,140 @@ +// $Id$ + +#include "Deployment_NodeApplicationC.h" +#include "Client_init.h" +#include "NodeAppTest_RoundTripC.h" +#include "ace/Get_Opt.h" +#include "assert.h" + +const char *ior = "file://test.ior"; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s \n" + "-k <ComponentServer ior> \n" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + try + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, ""); + + if (parse_args (argc, argv) != 0) + return 1; + + CIAO::Client_init (orb.in ()); + + CORBA::Object_var tmp = + orb->string_to_object(ior); + + Deployment::NodeApplication_var node_app = + Deployment::NodeApplication::_narrow(tmp.in ()); + + if (CORBA::is_nil (node_app.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil nodeapplication reference <%s>\n", + ior), + 1); + } + + + ACE_DEBUG ((LM_DEBUG, "Try installing Home and Component\n")); + + Deployment::ComponentImplementationInfo info; + + // Add the names and entry points of each of the DLLs + info.component_instance_name = + CORBA::string_dup ("NodeAppTest_RoundTrip"); + info.executor_dll = + CORBA::string_dup ("NodeAppTest_RoundTrip_exec"); + info.executor_entrypt = + CORBA::string_dup ("createRoundTripHome_Impl"); + info.servant_dll = + CORBA::string_dup ("NodeAppTest_RoundTrip_svnt"); + info.servant_entrypt = + CORBA::string_dup ( + "create_NodeAppTest_NodeAppTest_RoundTripHome_Servant" + ); + + // Create a ContainerImplementationInfo sequence + Deployment::ContainerImplementationInfo container_info; + container_info.impl_infos.length (1); + container_info.impl_infos[0] = info; + + // Create a NodeImplementationInfo sequence + Deployment::NodeImplementationInfo node_info; + node_info.impl_infos.length (1); + node_info.impl_infos[0] = container_info; + + // Install test component and its home on NodeApplication + Deployment::ComponentInfos_var comp_info = + node_app->install (node_info); + + assert (comp_info->length () == 1); //return 1 component objeref + + const CORBA::ULong i = 0; + Components::CCMObject_var objref = (comp_info[i]).component_ref; + + NodeAppTest::NodeAppTest_RoundTrip_var roundtrip_var = + NodeAppTest::NodeAppTest_RoundTrip::_narrow (objref.in ()); + + if (CORBA::is_nil (roundtrip_var.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil RoundTrip reference\n"), + 1); + } + + // Invoke Operation on the Interface + ACE_DEBUG ((LM_DEBUG, "Try cube_long operation on the Interface \n")); + CORBA::Long input = 1L; + CORBA::Long output = + roundtrip_var->cube_long (input); + + if (input == output) + ACE_DEBUG ((LM_DEBUG, "Retrun values matched!!\n")); + else + { + ACE_DEBUG ((LM_DEBUG, "Return values did not match: failure\n")); + ACE_OS::exit (1); + } + + ACE_DEBUG ((LM_DEBUG, "Try removing test component and its home\n")); + node_app->remove (); + ACE_DEBUG ((LM_DEBUG, "Component and Home removed successfully\n")); + + orb->destroy (); + ACE_DEBUG ((LM_DEBUG, "Test success!!\n")); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + return 1; + } + + return 0; +} diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/README b/modules/CIAO/DAnCE/tests/NodeApplicationTest/README new file mode 100644 index 00000000000..ea8fc438089 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/README @@ -0,0 +1,12 @@ +$Id$ +This directory contains the basic testing program for NodeApplication. + +client_simple: Test the basic home installation and component creation. + +client: Test the installation of several homes and components. + In this test I use the more convenient method provided + by the NodeApplication to insall multiple components. Aslo + a remove method is called to easily remove all homes and components. + +client_ex: Test the get_all_facet methods provided in the servant of the + component. diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec.cpp b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec.cpp new file mode 100644 index 00000000000..8cbd9270bd0 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec.cpp @@ -0,0 +1,149 @@ +// $Id$ + +#include "RoundTrip_exec.h" +#include "CIAO_common.h" + +//-- ACE Scheduling Params +#include "ace/OS_NS_errno.h" + +//================================================================= + +namespace CIDL_RoundTrip_Impl +{ + RoundTrip_exec_i::RoundTrip_exec_i () + { + + } + + RoundTrip_exec_i::~RoundTrip_exec_i () + { + } + + NodeAppTest::CCM_LatencyTest_ptr + RoundTrip_exec_i::get_facet_1 () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + return new LatencyTest_Impl; + } + + NodeAppTest::CCM_LatencyTest_ptr + RoundTrip_exec_i::get_facet_2 () + ACE_THROW_SPEC ((CORBA::SystemException)) + { + return new LatencyTest_Impl; + } + + CORBA::Long + RoundTrip_exec_i::cube_long (CORBA::Long data) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + return data * data * data; + } + + // Operations from Components::SessionComponent + void + RoundTrip_exec_i::set_session_context (Components::SessionContext_ptr) + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)) + { + if (CIAO::debug_level () > 0) + { + ACE_DEBUG ((LM_DEBUG, + "RoundTrip_exec_i::set_session_context\n")); + } + } + + void + RoundTrip_exec_i::ccm_activate () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)) + { + if (CIAO::debug_level () > 0) + { + ACE_DEBUG ((LM_DEBUG, "RoundTrip_exec_i::ccm_activate\n")); + } + + } + + void + RoundTrip_exec_i::ccm_passivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)) + { + if (CIAO::debug_level () > 0) + { + ACE_DEBUG ((LM_DEBUG, "RoundTrip_exec_i::ccm_passivate\n")); + } + } + + void + RoundTrip_exec_i::ccm_remove () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)) + { + if (CIAO::debug_level () > 0) + { + ACE_DEBUG ((LM_DEBUG, "RoundTrip_exec_i::ccm_remove\n")); + } + } + + void + RoundTrip_exec_i::ciao_preactivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)) + { + if (CIAO::debug_level () > 0) + { + ACE_DEBUG ((LM_DEBUG, "RoundTrip_exec_i::ciao_preactivate\n")); + } + + } + + void + RoundTrip_exec_i::ciao_postactivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)) + { + if (CIAO::debug_level () > 0) + { + ACE_DEBUG ((LM_DEBUG, "RoundTrip_exec_i::ciao_postactivate\n")); + } + } + + RoundTripHome_exec_i::RoundTripHome_exec_i () + { + } + + RoundTripHome_exec_i::~RoundTripHome_exec_i () + { + } + + ::Components::EnterpriseComponent_ptr + RoundTripHome_exec_i::create () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)) + { + return new RoundTrip_exec_i; + } + + // Implementation for the probided inferface. + CORBA::Long + LatencyTest_Impl::cube_long (CORBA::Long data) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + return data*data*data; + } + + extern "C" NODEAPPTEST_ROUNDTRIP_EXEC_Export + ::Components::HomeExecutorBase_ptr + createRoundTripHome_Impl (void) + { + if (CIAO::debug_level () > 0) + { + ACE_DEBUG ((LM_DEBUG, "Creating Round_trip impl\n")); + } + + return new RoundTripHome_exec_i (); + } +} + diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec.h b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec.h new file mode 100644 index 00000000000..2df0ce868c8 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec.h @@ -0,0 +1,149 @@ +// -*- C++ -*- + +//============================================================ +/** + * @file RoundTrip_exec.h + * + * $Id$ + * + * Header file for the Executor implementation. + * + * @author Arvind S. Krishna <arvindk@dre.vanderbilt.edu> + */ +//============================================================ + +#ifndef NODEAPP_ROUNDTRIP_EXEC_H +#define NODEAPP_ROUNDTRIP_EXEC_H + +#include "NodeAppTest_RoundTripEC.h" +#include "RoundTrip_exec_export.h" +#include "tao/LocalObject.h" + +namespace CIDL_RoundTrip_Impl +{ + + /** + * @class RoundTrip_exec_i + * + * RoundTrip executor implementation class. + */ + class NODEAPPTEST_ROUNDTRIP_EXEC_Export RoundTrip_exec_i + : public virtual NodeAppTest::LatencyTest, + public virtual RoundTrip_Exec, + public virtual TAO_Local_RefCounted_Object + { + + public: + /// Default constructor. + RoundTrip_exec_i (); + + /// Operation to test the data + virtual CORBA::Long cube_long (CORBA::Long data) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /* + virtual ::NodeAppTest::CCM_LatencyTest* + get_latency () + ACE_THROW_SPEC ((CORBA::SystemException)); + */ + + NodeAppTest::CCM_LatencyTest_ptr + get_facet_1() + ACE_THROW_SPEC ((CORBA::SystemException)); + + + NodeAppTest::CCM_LatencyTest_ptr + get_facet_2() + ACE_THROW_SPEC ((CORBA::SystemException)); + + // Operations from Components::SessionComponent + virtual void set_session_context (Components::SessionContext_ptr ctx) + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)); + + virtual void ccm_activate () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)); + + virtual void ccm_passivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)); + + virtual void ccm_remove () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)); + + /// Helper function to be called back by timeout_Handler + void pulse (void); + + // CIAO defined methods + virtual void ciao_preactivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)); + + virtual void ciao_postactivate () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)); + + protected: + + /// Destructor. + /** + * Protected destructor to enforce proper memory management + * through the reference counting mechanism. + */ + ~RoundTrip_exec_i (); + + }; + + // + // + // + class LatencyTest_Impl : public virtual NodeAppTest::CCM_LatencyTest, + public virtual TAO_Local_RefCounted_Object + { + public: + LatencyTest_Impl () + { + } + + virtual CORBA::Long cube_long (CORBA::Long data) + ACE_THROW_SPEC ((CORBA::SystemException)); + }; + + /** + * @class RoundTripHome_exec_i + * + * RoundTrip home executor implementation class. + */ + class NODEAPPTEST_ROUNDTRIP_EXEC_Export RoundTripHome_exec_i : + public virtual RoundTripHome_Exec, + public virtual TAO_Local_RefCounted_Object + { + public: + /// Default ctor. + RoundTripHome_exec_i (); + + // Implicit home operations. + + virtual ::Components::EnterpriseComponent_ptr + create () + ACE_THROW_SPEC ((CORBA::SystemException, + Components::CCMException)); + + protected: + + /// Destructor. + /** + * Protected destructor to enforce proper memory management + * through the reference counting mechanism. + */ + ~RoundTripHome_exec_i (); + + }; + + extern "C" NODEAPPTEST_ROUNDTRIP_EXEC_Export + ::Components::HomeExecutorBase_ptr createRoundTripHome_Impl (void); +} + +#endif /* NODEAPP_ROUNDTRIPGEN_EXEC_H */ diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec_export.h b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec_export.h new file mode 100644 index 00000000000..ba26507df22 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_exec_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl NODEAPPTEST_ROUNDTRIP_EXEC +// ------------------------------ +#ifndef NODEAPPTEST_ROUNDTRIP_EXEC_EXPORT_H +#define NODEAPPTEST_ROUNDTRIP_EXEC_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (NODEAPPTEST_ROUNDTRIP_EXEC_HAS_DLL) +# define NODEAPPTEST_ROUNDTRIP_EXEC_HAS_DLL 1 +#endif /* ! NODEAPPTEST_ROUNDTRIP_EXEC_HAS_DLL */ + +#if defined (NODEAPPTEST_ROUNDTRIP_EXEC_HAS_DLL) && (NODEAPPTEST_ROUNDTRIP_EXEC_HAS_DLL == 1) +# if defined (NODEAPPTEST_ROUNDTRIP_EXEC_BUILD_DLL) +# define NODEAPPTEST_ROUNDTRIP_EXEC_Export ACE_Proper_Export_Flag +# define NODEAPPTEST_ROUNDTRIP_EXEC_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define NODEAPPTEST_ROUNDTRIP_EXEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* NODEAPPTEST_ROUNDTRIP_EXEC_BUILD_DLL */ +# define NODEAPPTEST_ROUNDTRIP_EXEC_Export ACE_Proper_Import_Flag +# define NODEAPPTEST_ROUNDTRIP_EXEC_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define NODEAPPTEST_ROUNDTRIP_EXEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* NODEAPPTEST_ROUNDTRIP_EXEC_BUILD_DLL */ +#else /* NODEAPPTEST_ROUNDTRIP_EXEC_HAS_DLL == 1 */ +# define NODEAPPTEST_ROUNDTRIP_EXEC_Export +# define NODEAPPTEST_ROUNDTRIP_EXEC_SINGLETON_DECLARATION(T) +# define NODEAPPTEST_ROUNDTRIP_EXEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* NODEAPPTEST_ROUNDTRIP_EXEC_HAS_DLL == 1 */ + +// Set NODEAPPTEST_ROUNDTRIP_EXEC_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (NODEAPPTEST_ROUNDTRIP_EXEC_NTRACE) +# if (ACE_NTRACE == 1) +# define NODEAPPTEST_ROUNDTRIP_EXEC_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define NODEAPPTEST_ROUNDTRIP_EXEC_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !NODEAPPTEST_ROUNDTRIP_EXEC_NTRACE */ + +#if (NODEAPPTEST_ROUNDTRIP_EXEC_NTRACE == 1) +# define NODEAPPTEST_ROUNDTRIP_EXEC_TRACE(X) +#else /* (NODEAPPTEST_ROUNDTRIP_EXEC_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define NODEAPPTEST_ROUNDTRIP_EXEC_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (NODEAPPTEST_ROUNDTRIP_EXEC_NTRACE == 1) */ + +#endif /* NODEAPPTEST_ROUNDTRIP_EXEC_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_stub_export.h b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_stub_export.h new file mode 100644 index 00000000000..d82c188c509 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_stub_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl NODEAPPTEST_ROUNDTRIP_STUB +// ------------------------------ +#ifndef NODEAPPTEST_ROUNDTRIP_STUB_EXPORT_H +#define NODEAPPTEST_ROUNDTRIP_STUB_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (NODEAPPTEST_ROUNDTRIP_STUB_HAS_DLL) +# define NODEAPPTEST_ROUNDTRIP_STUB_HAS_DLL 1 +#endif /* ! NODEAPPTEST_ROUNDTRIP_STUB_HAS_DLL */ + +#if defined (NODEAPPTEST_ROUNDTRIP_STUB_HAS_DLL) && (NODEAPPTEST_ROUNDTRIP_STUB_HAS_DLL == 1) +# if defined (NODEAPPTEST_ROUNDTRIP_STUB_BUILD_DLL) +# define NODEAPPTEST_ROUNDTRIP_STUB_Export ACE_Proper_Export_Flag +# define NODEAPPTEST_ROUNDTRIP_STUB_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define NODEAPPTEST_ROUNDTRIP_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* NODEAPPTEST_ROUNDTRIP_STUB_BUILD_DLL */ +# define NODEAPPTEST_ROUNDTRIP_STUB_Export ACE_Proper_Import_Flag +# define NODEAPPTEST_ROUNDTRIP_STUB_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define NODEAPPTEST_ROUNDTRIP_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* NODEAPPTEST_ROUNDTRIP_STUB_BUILD_DLL */ +#else /* NODEAPPTEST_ROUNDTRIP_STUB_HAS_DLL == 1 */ +# define NODEAPPTEST_ROUNDTRIP_STUB_Export +# define NODEAPPTEST_ROUNDTRIP_STUB_SINGLETON_DECLARATION(T) +# define NODEAPPTEST_ROUNDTRIP_STUB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* NODEAPPTEST_ROUNDTRIP_STUB_HAS_DLL == 1 */ + +// Set NODEAPPTEST_ROUNDTRIP_STUB_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (NODEAPPTEST_ROUNDTRIP_STUB_NTRACE) +# if (ACE_NTRACE == 1) +# define NODEAPPTEST_ROUNDTRIP_STUB_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define NODEAPPTEST_ROUNDTRIP_STUB_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !NODEAPPTEST_ROUNDTRIP_STUB_NTRACE */ + +#if (NODEAPPTEST_ROUNDTRIP_STUB_NTRACE == 1) +# define NODEAPPTEST_ROUNDTRIP_STUB_TRACE(X) +#else /* (NODEAPPTEST_ROUNDTRIP_STUB_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define NODEAPPTEST_ROUNDTRIP_STUB_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (NODEAPPTEST_ROUNDTRIP_STUB_NTRACE == 1) */ + +#endif /* NODEAPPTEST_ROUNDTRIP_STUB_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_svnt_export.h b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_svnt_export.h new file mode 100644 index 00000000000..b84617f9ff0 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/RoundTrip_svnt_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl NODEAPPTEST_ROUNDTRIP_SVNT +// ------------------------------ +#ifndef NODEAPPTEST_ROUNDTRIP_SVNT_EXPORT_H +#define NODEAPPTEST_ROUNDTRIP_SVNT_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (NODEAPPTEST_ROUNDTRIP_SVNT_HAS_DLL) +# define NODEAPPTEST_ROUNDTRIP_SVNT_HAS_DLL 1 +#endif /* ! NODEAPPTEST_ROUNDTRIP_SVNT_HAS_DLL */ + +#if defined (NODEAPPTEST_ROUNDTRIP_SVNT_HAS_DLL) && (NODEAPPTEST_ROUNDTRIP_SVNT_HAS_DLL == 1) +# if defined (NODEAPPTEST_ROUNDTRIP_SVNT_BUILD_DLL) +# define NODEAPPTEST_ROUNDTRIP_SVNT_Export ACE_Proper_Export_Flag +# define NODEAPPTEST_ROUNDTRIP_SVNT_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define NODEAPPTEST_ROUNDTRIP_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* NODEAPPTEST_ROUNDTRIP_SVNT_BUILD_DLL */ +# define NODEAPPTEST_ROUNDTRIP_SVNT_Export ACE_Proper_Import_Flag +# define NODEAPPTEST_ROUNDTRIP_SVNT_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define NODEAPPTEST_ROUNDTRIP_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* NODEAPPTEST_ROUNDTRIP_SVNT_BUILD_DLL */ +#else /* NODEAPPTEST_ROUNDTRIP_SVNT_HAS_DLL == 1 */ +# define NODEAPPTEST_ROUNDTRIP_SVNT_Export +# define NODEAPPTEST_ROUNDTRIP_SVNT_SINGLETON_DECLARATION(T) +# define NODEAPPTEST_ROUNDTRIP_SVNT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* NODEAPPTEST_ROUNDTRIP_SVNT_HAS_DLL == 1 */ + +// Set NODEAPPTEST_ROUNDTRIP_SVNT_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (NODEAPPTEST_ROUNDTRIP_SVNT_NTRACE) +# if (ACE_NTRACE == 1) +# define NODEAPPTEST_ROUNDTRIP_SVNT_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define NODEAPPTEST_ROUNDTRIP_SVNT_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !NODEAPPTEST_ROUNDTRIP_SVNT_NTRACE */ + +#if (NODEAPPTEST_ROUNDTRIP_SVNT_NTRACE == 1) +# define NODEAPPTEST_ROUNDTRIP_SVNT_TRACE(X) +#else /* (NODEAPPTEST_ROUNDTRIP_SVNT_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define NODEAPPTEST_ROUNDTRIP_SVNT_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (NODEAPPTEST_ROUNDTRIP_SVNT_NTRACE == 1) */ + +#endif /* NODEAPPTEST_ROUNDTRIP_SVNT_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test.pl b/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test.pl new file mode 100755 index 00000000000..11d7801b133 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test.pl @@ -0,0 +1,47 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{'ACE_ROOT'}/bin"; +use PerlACE::Run_Test; + +$status = 0; +$iorfile = PerlACE::LocalFile ("test.ior"); + +for ($iter = 0; $iter <= $#ARGV; $iter++) { + if ($ARGV[$iter] eq "-h" || $ARGV[$iter] eq "-?") { + print "Run_Test Perl script for NodeApplicationTest \n\n"; + print "run_test \n"; + print "\n"; + print "-h -- prints this information\n"; + exit 0; + } +} + + +unlink $iorfile; +$CIAO_ROOT=$ENV{'CIAO_ROOT'}; + +$SV = new PerlACE::Process ("../../NodeApplication/NodeApplication", + "-n -o $iorfile"); + +$CL = new PerlACE::Process ("client", + "-k file://$iorfile -n 4"); + +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($iorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$iorfile>\n"; + $SV->Kill (); + exit 1; +} + +$CL->SpawnWaitKill (10); +$status = $SV->Kill (); $SV->TimedWait (1); + +unlink $iorfile; + +exit $status; diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test_ex.pl b/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test_ex.pl new file mode 100755 index 00000000000..0fd413091f0 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test_ex.pl @@ -0,0 +1,47 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{'ACE_ROOT'}/bin"; +use PerlACE::Run_Test; + +$status = 0; +$iorfile = PerlACE::LocalFile ("test.ior"); + +for ($iter = 0; $iter <= $#ARGV; $iter++) { + if ($ARGV[$iter] eq "-h" || $ARGV[$iter] eq "-?") { + print "Run_Test Perl script for NodeApplicationTest \n\n"; + print "run_test \n"; + print "\n"; + print "-h -- prints this information\n"; + exit 0; + } +} + + +unlink $iorfile; +$CIAO_ROOT=$ENV{'CIAO_ROOT'}; + +$SV = new PerlACE::Process ("../../NodeApplication/NodeApplication", + "-n -o $iorfile"); + +$CL = new PerlACE::Process ("client_ex", + "-k file://$iorfile"); + +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($iorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$iorfile>\n"; + $SV->Kill (); + exit 1; +} + +$CL->SpawnWaitKill (10); +$status = $SV->Kill (); $SV->TimedWait (1); + +unlink $iorfile; + +exit $status; diff --git a/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test_simple.pl b/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test_simple.pl new file mode 100755 index 00000000000..c1811abee9d --- /dev/null +++ b/modules/CIAO/DAnCE/tests/NodeApplicationTest/run_test_simple.pl @@ -0,0 +1,47 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{'ACE_ROOT'}/bin"; +use PerlACE::Run_Test; + +$status = 0; +$iorfile = PerlACE::LocalFile ("test.ior"); + +for ($iter = 0; $iter <= $#ARGV; $iter++) { + if ($ARGV[$iter] eq "-h" || $ARGV[$iter] eq "-?") { + print "Run_Test Perl script for NodeApplicationTest \n\n"; + print "run_test \n"; + print "\n"; + print "-h -- prints this information\n"; + exit 0; + } +} + + +unlink $iorfile; +$CIAO_ROOT=$ENV{'CIAO_ROOT'}; + +$SV = new PerlACE::Process ("../../NodeApplication/NodeApplication", + "-n -o $iorfile"); + +$CL = new PerlACE::Process ("client_simple", + "-k file://$iorfile "); + +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($iorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$iorfile>\n"; + $SV->Kill (); + exit 1; +} + +$CL->SpawnWaitKill (10); +$status = $SV->Kill (); $SV->TimedWait (1); + +unlink $iorfile; + +exit $status; diff --git a/modules/CIAO/DAnCE/tests/scripts/BasicSP/basicNodeDaemon.pl b/modules/CIAO/DAnCE/tests/scripts/BasicSP/basicNodeDaemon.pl new file mode 100755 index 00000000000..59d86f5c9f1 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/scripts/BasicSP/basicNodeDaemon.pl @@ -0,0 +1,62 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; + +$status = 0; +$iorfile1 = PerlACE::LocalFile ("NodeApp1.ior"); +$iorfile2 = PerlACE::LocalFile ("NodeApp2.ior"); +$iorfile3 = PerlACE::LocalFile ("NodeApp3.ior"); +$iorfile4 = PerlACE::LocalFile ("NodeApp4.ior"); +$iorfile5 = PerlACE::LocalFile ("NodeApp5.ior"); + +#for ($iter = 0; $iter <= $#ARGV; $iter++) { +# if ($ARGV[$iter] eq "-h" || $ARGV[$iter] eq "-?") { +# print "Run_Test Perl script for NodeApplicationTest \n\n"; +# print "run_test \n"; +# print "\n"; +# print "-h -- prints this information\n"; +# exit 0; +# } +#} + + +unlink $iorfile1; +unlink $iorfile2; +unlink $iorfile3; +unlink $iorfile4; +unlink $iorfile5; + +$CIAO_ROOT=$ENV{'CIAO_ROOT'}; + +$SV1 = new PerlACE::Process ("$CIAO_ROOT/DAnCE/NodeManager/NodeManager", + "-ORBEndpoint iiop://localhost:10000 -s +$CIAO_ROOT/DAnCE/NodeApplication/NodeApplication"); + +$SV2 = new PerlACE::Process ("$CIAO_ROOT/DAnCE/NodeManager/NodeManager", + "-ORBEndpoint iiop://localhost:20000 -s +$CIAO_ROOT/DAnCE/NodeApplication/NodeApplication"); + +$SV3 = new PerlACE::Process ("$CIAO_ROOT/DAnCE/NodeManager/NodeManager", + "-ORBEndpoint iiop://localhost:30000 -s +$CIAO_ROOT/DAnCE/NodeApplication/NodeApplication"); + +$SV4 = new PerlACE::Process ("$CIAO_ROOT/DAnCE/NodeManager/NodeManager", + "-ORBEndpoint iiop://localhost:40000 -s +$CIAO_ROOT/DAnCE/NodeApplication/NodeApplication"); + +$SV5 = new PerlACE::Process ("$CIAO_ROOT/DAnCE/NodeManager/NodeManager", + "-ORBEndpoint iiop://localhost:50000 -s +$CIAO_ROOT/DAnCE/NodeApplication/NodeApplication"); +$SV1->Spawn (); +$SV2->Spawn (); +$SV3->Spawn (); +$SV4->Spawn (); +$SV5->Spawn (); + +sleep (99999999999); diff --git a/modules/CIAO/DAnCE/tests/scripts/BasicSP/basicsp.dat b/modules/CIAO/DAnCE/tests/scripts/BasicSP/basicsp.dat new file mode 100644 index 00000000000..8bd5e6a72f6 --- /dev/null +++ b/modules/CIAO/DAnCE/tests/scripts/BasicSP/basicsp.dat @@ -0,0 +1,3 @@ +BMClosedED corbaloc:iiop:localhost:10000/NodeManager +EC corbaloc:iiop:localhost:20000/NodeManager + |