summaryrefslogtreecommitdiff
path: root/TAO/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp')
-rw-r--r--TAO/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp449
1 files changed, 372 insertions, 77 deletions
diff --git a/TAO/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp b/TAO/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp
index 9f790eb4d45..df31c704651 100644
--- a/TAO/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp
+++ b/TAO/CIAO/DAnCE/NodeApplicationManager/Containers_Info_Map.cpp
@@ -1,19 +1,53 @@
// $Id$
+
#include "Containers_Info_Map.h"
#include "ciao/CIAO_Config.h"
#include "ciao/CIAO_common.h"
+//Added for HTTP
+#include "URL_Parser.h" //for parsing the URL
+#include "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
+
+
namespace CIAO
{
Containers_Info_Map::
- Containers_Info_Map (const Deployment::DeploymentPlan & plan)
+ Containers_Info_Map (const Deployment::DeploymentPlan & plan,
+ const Deployment::ComponentPlans & shared_components)
: map_ (CIAO_DEFAULT_MAP_SIZE),
- plan_ (plan)
+ plan_ (plan),
+ shared_components_ (shared_components),
+ HTTP_DOWNLOAD_PATH ()
{
+ char* temp = ACE_OS::getenv ("CIAO_ROOT");
+ HTTP_DOWNLOAD_PATH += temp;
+
+#if defined (ACE_WIN32) || defined (ACE_WIN64)
+ 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
+
+ //now lets update the loader path to include
+ //the HTTP_DOWNLOAD_PATH
+ this->update_loader_path ();
+
+
this->initialize_map ();
this->build_map ();
}
-
+
Deployment::ContainerImplementationInfos *
Containers_Info_Map::containers_info (void)
{
@@ -21,7 +55,7 @@ namespace CIAO
// and return the corresponding sequence
Deployment::ContainerImplementationInfos_var retv;
- ACE_NEW_RETURN (retv,
+ ACE_NEW_RETURN (retv,
Deployment::ContainerImplementationInfos,
0);
@@ -39,7 +73,7 @@ namespace CIAO
}
return retv._retn ();
}
-
+
void
Containers_Info_Map::
initialize_map (void)
@@ -49,82 +83,111 @@ namespace CIAO
// 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)
{
- const char * my_resource_id = "";
- const char * my_policy_set_id = "";
+ CORBA::String_var my_resource_id ("");
+ const char *my_policy_set_id = "";
if (this->plan_.instance[i].deployedResource.length () != 0)
{
- my_resource_id =
+ /*
+ my_resource_id =
this->plan_.instance[i].deployedResource[0].resourceName.in ();
this->plan_.instance[i].deployedResource[0].resourceValue >>=
my_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."));
}
- // If we find a different policy_set_id, then we bind it.
+ // If we find a existing policy_set_id, then do nothing.
if (this->map_.find (my_policy_set_id) == 0)
continue;
- else if (ACE_OS::strcmp (my_policy_set_id, "") == 0)
+ if (ACE_OS::strcmp (my_policy_set_id, "") == 0)
{
- // empty policy_set_id
+ // 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;
- for (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,
- my_resource_id) == 0)
- {
- // Iterate over the policy_sets
- CORBA::ULong k;
- for (k = 0;
- k < (*server_resource_def).orb_config.policy_set.length ();
- ++k)
- {
- 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 <<=
- (*server_resource_def).orb_config.policy_set[k];
- }
- }
- if (k == (*server_resource_def).orb_config.policy_set.length ())
- {
- // No Server Resource Def found?
- ACE_DEBUG ((LM_DEBUG, "No matching policy set def found!\n"));
- }
- }
- } // end of for loop for fetching policy_set_def
+ {
+ Deployment::ContainerImplementationInfo * info;
+ ACE_NEW (info, Deployment::ContainerImplementationInfo);
- if (j == this->plan_.infoProperty.length ())
- {
- // No Server Resource Def found?! Inconsistent descriptor files.
- ACE_DEBUG ((LM_ERROR, "(%P|%t) Descriptor error: "
- "No matching server resrouce def found for component: %s!\n",
- this->plan_.instance[i].name.in ()));
- }
- this->map_.bind (my_policy_set_id, info);
- }
+ // 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_DEBUG ((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);
+ }
}
}
@@ -139,6 +202,12 @@ namespace CIAO
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;
}
@@ -155,17 +224,18 @@ namespace CIAO
const char * policy_set_id = "";
if (instance.deployedResource.length () != 0)
{
- instance.deployedResource[0].resourceValue >>= 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;
+ 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,
+ instance,
entry->int_id_->impl_infos);
}
@@ -199,12 +269,41 @@ namespace CIAO
bool svnt_found = false;
bool exec_found = false;
- // For svnt artifact
+ // For svnt/exec artifacts
for (CORBA::ULong j = 0; j < artifact_num; ++j)
{
const Deployment::ArtifactDeploymentDescription & arti =
this->plan_.artifact[ impl.artifactRef[j] ];
+#if defined (ACE_WIN32) || defined (ACE_WIN64)
+ 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;
+ if (!this->resolve_http_reference (arti.location[loc_num],
+ 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 ()));
+
+ arti.location[loc_num] = CORBA::string_dup ("HTTP_failure");
+ }
+ else
+ {
+ arti.location[loc_num] = CORBA::string_dup (arti.name.in ());
+ //enque for cleanup
+ }
+ }
+ }
+#endif
+
ACE_CString tmp = arti.name.in ();
ssize_t pos;
@@ -212,9 +311,13 @@ namespace CIAO
// 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))
+ (pos = tmp.find ("_Svnt")) != ACE_CString::npos))
{
if (arti.location.length() < 1 )
{
@@ -225,20 +328,20 @@ namespace CIAO
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].in ());
+ impl_infos[i].servant_dll =
+ CORBA::string_dup (arti.location[0]);
// Get the entry point.
- const CORBA::ULong prop_length = arti.execParameter.length ();
+ const CORBA::ULong prop_length = arti.execParameter.length ();
for (CORBA::ULong prop_num = 0;
- prop_num < prop_length;
- ++prop_num)
+ prop_num < prop_length;
+ ++prop_num)
{
ACE_CString name (arti.execParameter[prop_num].name.in ());
if (name == ACE_CString ("entryPoint"))
{
- const char * entry;
+ const char * entry = 0;
(arti.execParameter[prop_num].value) >>= entry;
impl_infos[i].servant_entrypt = CORBA::string_dup (entry);
}
@@ -248,13 +351,15 @@ namespace CIAO
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))
+ (pos = tmp.find ("_Exec")) != ACE_CString::npos))
{
if (arti.location.length() < 1 )
{
@@ -263,22 +368,22 @@ namespace CIAO
}
exec_found = true;
- // Cpoy the servant dll/so name.
+ // 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].in ());
+ 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)
+ prop_num < prop_length;
+ ++prop_num)
{
ACE_CString name (arti.execParameter[prop_num].name.in ());
if (name == ACE_CString ("entryPoint"))
{
- const char * entry;
+ const char * entry = 0;
(arti.execParameter[prop_num].value) >>= entry;
impl_infos[i].executor_entrypt = CORBA::string_dup (entry);
}
@@ -296,3 +401,193 @@ namespace CIAO
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) || defined (ACE_WIN64)
+ 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) || defined (ACE_WIN64)
+ ACE_CString new_path = "PATH=";
+#else
+ ACE_CString new_path = "LD_LIBRARY_PATH=";
+#endif
+
+ new_path += this->HTTP_DOWNLOAD_PATH;
+
+#if defined (ACE_WIN32) || defined (ACE_WIN64)
+ new_path += ";";
+#else
+ new_path += ":";
+#endif
+
+ new_path += path;
+
+//turn off the HTTP feature for Linux until
+//I discover what the problem with Linux is
+#if defined (ACE_WIN32) || defined (ACE_WIN64)
+ ACE_OS::putenv (new_path.c_str ());
+#endif
+
+ }
+
+ //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 &path)
+ {
+
+ ACE_DEBUG ((LM_INFO,
+ "Attempting to download %s\n",
+ location));
+
+ //figure out the file name
+ char* name = const_cast<char*> (location);
+ char* p = NULL;
+ while (1)
+ {
+ if (p = ACE_OS::strstr (name, "/"))
+ {
+ name = ++p;
+ continue;
+ }
+ else if (p = ACE_OS::strstr (name, "\\"))
+ {
+ name = ++p;
+ continue;
+ }
+ else
+ break;
+ }
+
+ //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;
+ }
+
+ path = HTTP_DOWNLOAD_PATH;
+ path += "/";
+ path += 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)
+ {
+ URL_Parser *parser = TheURL_Parser::instance ();
+ if (!parser->parseURL (const_cast<char*> (URL)))
+ return false;
+
+ // Create a client
+ 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;
+ }