summaryrefslogtreecommitdiff
path: root/modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.cpp')
-rw-r--r--modules/CIAO/DAnCE/NodeApplicationManager/NodeApplicationManager_Impl.cpp1161
1 files changed, 1161 insertions, 0 deletions
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)
+{
+}
+