summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp')
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp574
1 files changed, 574 insertions, 0 deletions
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
new file mode 100644
index 00000000000..8d5c0cd2eee
--- /dev/null
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
@@ -0,0 +1,574 @@
+#include "Locator_Repository.h"
+#include "Locator_XMLHandler.h"
+#include "utils.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/OS_NS_unistd.h"
+
+#include "ACEXML/parser/parser/Parser.h"
+#include "ACEXML/common/FileCharStream.h"
+#include "ACEXML/common/XML_Util.h"
+
+ACE_RCSID (ImplRepo_Service, Locator_Repository, "$Id$")
+
+static const char* STARTUP_COMMAND = "StartupCommand";
+static const char* WORKING_DIR = "WorkingDir";
+static const char* ENVIRONMENT = "Environment";
+static const char* ACTIVATION = "Activation";
+static const char* PARTIAL_IOR = "Location";
+static const char* IOR = "IOR";
+static const char* START_LIMIT = "StartLimit";
+static const char* ACTIVATOR = "Activator";
+static const char* SERVERS_ROOT_KEY = "Servers";
+static const char* ACTIVATORS_ROOT_KEY = "Activators";
+static const char* TOKEN = "Token";
+
+#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
+static const char* WIN32_REG_KEY = "Software\\TAO\\ImplementationRepository";
+#endif
+
+static ACE_CString lcase (const ACE_CString& s)
+{
+ ACE_CString ret(s);
+ for (size_t i = 0; i < ret.length (); ++i)
+ {
+ ret[i] = static_cast<char>(ACE_OS::ace_tolower (s[i]));
+ }
+ return ret;
+}
+
+static void loadActivatorsAsBinary (ACE_Configuration& config, Locator_Repository::AIMap& map)
+{
+ ACE_Configuration_Section_Key root;
+ int err = config.open_section (config.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
+ if (err == 0)
+ {
+ int index = 0;
+ ACE_CString name;
+ while (config.enumerate_sections (root, index, name) == 0)
+ {
+ ACE_CString ior;
+ u_int token;
+
+ ACE_Configuration_Section_Key key;
+
+ // Can't fail, because we're enumerating
+ config.open_section (root, name.c_str(), 0, key);
+
+ config.get_string_value (key, IOR, ior);
+ config.get_integer_value (key, TOKEN, token);
+
+ Activator_Info_Ptr info (new Activator_Info (name, token, ior));
+ map.bind (lcase (name), info);
+ index++;
+ }
+ }
+}
+
+static void loadServersAsBinary(ACE_Configuration& config, Locator_Repository::SIMap& map)
+{
+ ACE_Configuration_Section_Key root;
+ int err = config.open_section (config.root_section (), SERVERS_ROOT_KEY, 0, root);
+ if (err == 0)
+ {
+ int index = 0;
+ ACE_CString name;
+ while (config.enumerate_sections (root, index, name) == 0)
+ {
+ ACE_CString cmdline, dir, envstr, partial_ior, ior, aname;
+ u_int amodeint = ImplementationRepository::MANUAL;
+ u_int start_limit;
+
+ ACE_Configuration_Section_Key key;
+
+ // Can't fail, because we're enumerating
+ config.open_section (root, name.c_str (), 0, key);
+
+ // Ignore any missing values. Server name is enough on its own.
+ config.get_string_value (key, ACTIVATOR, aname);
+ config.get_string_value (key, STARTUP_COMMAND, cmdline);
+ config.get_string_value (key, WORKING_DIR, dir);
+ config.get_string_value (key, ENVIRONMENT, envstr);
+ config.get_integer_value(key, ACTIVATION, amodeint);
+ config.get_string_value (key, PARTIAL_IOR, partial_ior);
+ config.get_string_value (key, IOR, ior);
+ config.get_integer_value(key, START_LIMIT, start_limit);
+
+ ImplementationRepository::ActivationMode amode =
+ static_cast <ImplementationRepository::ActivationMode> (amodeint);
+
+ ImplementationRepository::EnvironmentList env_vars =
+ ImR_Utils::parseEnvList (envstr);
+
+ Server_Info_Ptr info (new Server_Info(name, aname, cmdline,
+ env_vars, dir, amode, start_limit, partial_ior, ior));
+ map.bind (name, info);
+ index++;
+ }
+ }
+}
+
+static void loadAsBinary (ACE_Configuration& config, Locator_Repository& repo)
+{
+ loadServersAsBinary (config, repo.servers ());
+ loadActivatorsAsBinary (config, repo.activators ());
+}
+
+// Note : There is no saveAsBinary(), because the ACE_Configuration class
+// supports saving of individual entries.
+
+static void convertEnvList (const Locator_XMLHandler::EnvList& in, ImplementationRepository::EnvironmentList& out)
+{
+ CORBA::ULong sz = in.size ();
+ out.length (sz);
+ for (CORBA::ULong i = 0; i < sz; ++i)
+ {
+ out[i].name = in[i].name.c_str ();
+ out[i].value = in[i].value.c_str ();
+ }
+}
+
+class Server_Repo_XML_Callback : public Locator_XMLHandler::Callback
+{
+public:
+ Server_Repo_XML_Callback(Locator_Repository& repo)
+ : repo_ (repo)
+ {
+ }
+ virtual void next_server (const ACE_CString& name,
+ const ACE_CString& aname, const ACE_CString& cmdline,
+ const Locator_XMLHandler::EnvList& envlst, const ACE_CString& dir,
+ const ACE_CString& amodestr, int start_limit,
+ const ACE_CString& partial_ior, const ACE_CString& ior)
+ {
+ ImplementationRepository::ActivationMode amode =
+ ImR_Utils::parseActivationMode (amodestr);
+
+ ImplementationRepository::EnvironmentList env_vars;
+ convertEnvList (envlst, env_vars);
+
+ int limit = start_limit < 1 ? 1 : start_limit;
+
+ Server_Info_Ptr si (new Server_Info (name, aname, cmdline,
+ env_vars, dir, amode, limit, partial_ior, ior));
+
+ this->repo_.servers ().bind (name, si);
+ }
+ virtual void next_activator (const ACE_CString& aname,
+ long token,
+ const ACE_CString& ior)
+ {
+ Activator_Info_Ptr si (new Activator_Info (aname, token, ior));
+ this->repo_.activators ().bind (lcase (aname), si);
+ }
+private:
+ Locator_Repository& repo_;
+};
+
+static int loadAsXML (const ACE_CString& fname, Locator_Repository& repo)
+{
+ ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; // xml input source will take ownership
+
+ if (fstm->open (fname.c_str()) != 0)
+ {
+ // This is not a real error. The xml file may not exist yet.
+ delete fstm;
+ return 0;
+ }
+
+ Server_Repo_XML_Callback cb (repo);
+
+ Locator_XMLHandler handler (cb);
+
+ ACEXML_Parser parser;
+
+ // InputSource takes ownership
+ ACEXML_InputSource input (fstm);
+
+ parser.setContentHandler (&handler);
+ parser.setDTDHandler (&handler);
+ parser.setErrorHandler (&handler);
+ parser.setEntityResolver (&handler);
+
+ ACEXML_TRY_NEW_ENV
+ {
+ parser.parse (&input ACEXML_ENV_ARG_PARAMETER);
+ ACEXML_TRY_CHECK;
+ }
+ ACEXML_CATCH (ACEXML_Exception, ex)
+ {
+ ACE_ERROR ((LM_ERROR, "Error during load of ImR persistence xml file."));
+ ex.print ();
+ return -1;
+ }
+ ACEXML_ENDTRY;
+ return 0;
+}
+
+// Note : Would pass servers by const&, but ACE hash map const_iterator is broken.
+static void saveAsXML (const ACE_CString& fname, Locator_Repository& repo)
+{
+ FILE* fp = ACE_OS::fopen (fname.c_str (), "w");
+ if (fp == 0)
+ {
+ ACE_ERROR ((LM_ERROR, "Couldn't write to file %s\n", fname.c_str()));
+ return;
+ }
+ ACE_OS::fprintf (fp,"<?xml version=\"1.0\"?>\n");
+ ACE_OS::fprintf (fp,"<%s>\n", Locator_XMLHandler::ROOT_TAG);
+
+ // Save servers
+ Locator_Repository::SIMap::ENTRY* sientry = 0;
+ Locator_Repository::SIMap::ITERATOR siit (repo.servers ());
+ for (; siit.next (sientry); siit.advance() )
+ {
+ Server_Info_Ptr& info = sientry->int_id_;
+
+ ACE_CString name = ACEXML_escape_string (info->name);
+ ACE_CString activator = ACEXML_escape_string (info->activator);
+ ACE_CString cmdline = ACEXML_escape_string (info->cmdline);
+ ACE_CString wdir = ACEXML_escape_string (info->dir);
+ ACE_CString partial_ior = ACEXML_escape_string (info->partial_ior);
+ ACE_CString ior = ACEXML_escape_string (info->ior);
+
+ ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::SERVER_INFO_TAG);
+ ACE_OS::fprintf (fp," name=\"%s\"", name.c_str ());
+ ACE_OS::fprintf (fp," activator=\"%s\"", activator.c_str ());
+ ACE_OS::fprintf (fp," command_line=\"%s\"", cmdline.c_str ());
+ ACE_OS::fprintf (fp," working_dir=\"%s\"", wdir.c_str ());
+ ACE_CString amodestr = ImR_Utils::activationModeToString (info->activation_mode);
+ ACE_OS::fprintf (fp," activation_mode=\"%s\"", amodestr.c_str ());
+ ACE_OS::fprintf (fp," start_limit=\"%d\"", info->start_limit);
+ ACE_OS::fprintf (fp," partial_ior=\"%s\"", partial_ior.c_str ());
+ ACE_OS::fprintf (fp," ior=\"%s\"", ior.c_str ());
+ ACE_OS::fprintf (fp,">\n");
+
+ for (CORBA::ULong i = 0; i < info->env_vars.length (); ++i)
+ {
+ ACE_OS::fprintf (fp,"\t\t<%s", Locator_XMLHandler::ENVIRONMENT_TAG);
+ ACE_OS::fprintf (fp," name=\"%s\"", info->env_vars[i].name.in ());
+ ACE_CString val = ACEXML_escape_string (info->env_vars[i].value.in ());
+ ACE_OS::fprintf (fp," value=\"%s\"", val.c_str ());
+ ACE_OS::fprintf (fp,"/>\n");
+ }
+
+ ACE_OS::fprintf (fp,"\t</%s>\n", Locator_XMLHandler::SERVER_INFO_TAG);
+ }
+
+ // Save Activators
+ Locator_Repository::AIMap::ENTRY* aientry = 0;
+ Locator_Repository::AIMap::ITERATOR aiit (repo.activators ());
+ for (; aiit.next (aientry); aiit.advance ())
+ {
+ ACE_CString aname = aientry->ext_id_;
+ Activator_Info_Ptr& info = aientry->int_id_;
+ ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::ACTIVATOR_INFO_TAG);
+ ACE_OS::fprintf( fp," name=\"%s\"", aname.c_str ());
+ ACE_OS::fprintf (fp," token=\"%d\"", info->token);
+ ACE_OS::fprintf (fp," ior=\"%s\"", info->ior.c_str ());
+ ACE_OS::fprintf (fp,"/>\n");
+ }
+
+ ACE_OS::fprintf (fp,"</%s>\n", Locator_XMLHandler::ROOT_TAG);
+ ACE_OS::fclose (fp);
+}
+
+Locator_Repository::Locator_Repository ()
+: rmode_ (Options::REPO_NONE)
+, config_ (0)
+{
+}
+
+int
+Locator_Repository::init(const Options& opts)
+{
+ this->rmode_ = opts.repository_mode ();
+ this->fname_ = opts.persist_file_name ();
+
+ int err = 0;
+ switch (this->rmode_)
+ {
+ case Options::REPO_NONE:
+ {
+ break;
+ }
+ case Options::REPO_HEAP_FILE:
+ {
+ if (opts.repository_erase ())
+ {
+ ACE_OS::unlink ( this->fname_.c_str () );
+ }
+ ACE_Configuration_Heap* heap = new ACE_Configuration_Heap ();
+ this->config_.reset (heap);
+ err = heap->open (this->fname_.c_str ());
+ if (err == 0)
+ {
+ loadAsBinary (*this->config_, *this);
+ }
+ break;
+ }
+ case Options::REPO_REGISTRY:
+ {
+#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
+ if (opts.repository_erase ())
+ {
+ ACE_Configuration_Win32Registry config ( HKEY_LOCAL_MACHINE );
+ ACE_Configuration_Section_Key root;
+ config.open_section (config.root_section(), "Software\\TAO", 0, root);
+ config.remove_section (root, "ImplementationRepository", 1);
+ }
+ HKEY root = ACE_Configuration_Win32Registry::
+ resolve_key (HKEY_LOCAL_MACHINE, WIN32_REG_KEY);
+ this->config_.reset (new ACE_Configuration_Win32Registry( root));
+ loadAsBinary (*this->config_, *this);
+#else
+ ACE_ERROR ((LM_ERROR, "Registry persistence is only "
+ "supported on Windows\n"));
+ err = -1;
+#endif
+ break;
+ }
+ case Options::REPO_XML_FILE:
+ {
+ if (opts.repository_erase ())
+ {
+ ACE_OS::unlink ( this->fname_.c_str() );
+ }
+ err = loadAsXML (this->fname_, *this);
+ break;
+ }
+ default:
+ {
+ bool invalid_rmode_specified = false;
+ ACE_ASSERT (invalid_rmode_specified);
+ ACE_UNUSED_ARG (invalid_rmode_specified);
+ err = -1;
+ }
+ }
+ return err;
+}
+
+int
+Locator_Repository::add_server (const ACE_CString& name,
+ const ACE_CString& aname,
+ const ACE_CString& startup_command,
+ const ImplementationRepository::EnvironmentList& env_vars,
+ const ACE_CString& working_dir,
+ ImplementationRepository::ActivationMode activation,
+ int start_limit,
+ const ACE_CString& partial_ior,
+ const ACE_CString& ior,
+ ImplementationRepository::ServerObject_ptr svrobj)
+{
+ int limit = start_limit < 1 ? 1 : start_limit;
+ Server_Info_Ptr info(new Server_Info (name, aname, startup_command,
+ env_vars, working_dir, activation, limit, partial_ior, ior, svrobj));
+
+ int err = servers ().bind (name, info);
+ if (err != 0)
+ {
+ return err;
+ }
+ this->update_server (*info);
+ return 0;
+}
+
+int
+Locator_Repository::add_activator (const ACE_CString& name,
+ const CORBA::Long token,
+ const ACE_CString& ior,
+ ImplementationRepository::Activator_ptr act)
+{
+ Activator_Info_Ptr info (new Activator_Info (name, token, ior, act));
+
+ int err = activators ().bind (lcase (name), info);
+ if (err != 0)
+ {
+ return err;
+ }
+ this->update_activator (*info);
+ return 0;
+}
+
+int
+Locator_Repository::update_server (const Server_Info& info)
+{
+ if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
+ {
+ ACE_ASSERT (this->config_.get () != 0);
+
+ ACE_Configuration& cfg = *this->config_;
+
+ ACE_Configuration_Section_Key root;
+ ACE_Configuration_Section_Key key;
+ int err = cfg.open_section (cfg.root_section(), SERVERS_ROOT_KEY, 1, root);
+ if (err != 0)
+ {
+ ACE_ERROR ((LM_ERROR, "Unable to open config section:%s\n", SERVERS_ROOT_KEY));
+ return err;
+ }
+ err = cfg.open_section (root, info.name.c_str (), 1, key);
+ if (err != 0)
+ {
+ ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str()));
+ return err;
+ }
+
+ ACE_CString envstr = ImR_Utils::envListToString(info.env_vars);
+
+ cfg.set_string_value (key, ACTIVATOR, info.activator.c_str ());
+ cfg.set_string_value (key, STARTUP_COMMAND, info.cmdline.c_str ());
+ cfg.set_string_value (key, WORKING_DIR, info.dir.c_str ());
+ cfg.set_string_value (key, ENVIRONMENT, envstr);
+ cfg.set_integer_value (key, ACTIVATION, info.activation_mode);
+ cfg.set_integer_value (key, START_LIMIT, info.start_limit);
+ cfg.set_string_value (key, PARTIAL_IOR, info.partial_ior.c_str ());
+ cfg.set_string_value (key, IOR, info.ior.c_str());
+ }
+ else if (rmode_ == Options::REPO_XML_FILE)
+ {
+ saveAsXML (this->fname_, *this);
+ }
+ return 0;
+}
+
+int
+Locator_Repository::update_activator (const Activator_Info& info)
+{
+ if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
+ {
+ ACE_ASSERT(this->config_.get () != 0);
+
+ ACE_Configuration& cfg = *this->config_;
+
+ ACE_Configuration_Section_Key root;
+ ACE_Configuration_Section_Key key;
+ int err = cfg.open_section (cfg.root_section(), ACTIVATORS_ROOT_KEY, 1, root);
+ if (err != 0)
+ {
+ ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", ACTIVATORS_ROOT_KEY));
+ return err;
+ }
+ err = cfg.open_section (root, info.name.c_str (), 1, key);
+ if (err != 0)
+ {
+ ACE_ERROR((LM_ERROR, "Unable to open config section:%s\n", info.name.c_str()));
+ return err;
+ }
+
+ cfg.set_integer_value (key, TOKEN, info.token);
+ cfg.set_string_value (key, IOR, info.ior.c_str ());
+ }
+ else if (rmode_ == Options::REPO_XML_FILE)
+ {
+ saveAsXML( this->fname_, *this);
+ }
+ return 0;
+}
+
+Server_Info_Ptr
+Locator_Repository::get_server (const ACE_CString& name)
+{
+ Server_Info_Ptr server (0);
+ servers ().find (name, server);
+ return server;
+}
+
+Activator_Info_Ptr
+Locator_Repository::get_activator (const ACE_CString& name)
+{
+ Activator_Info_Ptr activator (0);
+ activators ().find (lcase (name), activator);
+ return activator;
+}
+
+bool
+Locator_Repository::has_activator (const ACE_CString& name)
+{
+ Activator_Info_Ptr activator (0);
+ return activators().find (lcase (name), activator) == 0;
+}
+
+int
+Locator_Repository::remove_server (const ACE_CString& name)
+{
+ int ret = this->servers().unbind (name);
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
+ {
+ ACE_ASSERT (this->config_.get() != 0);
+ ACE_Configuration& cfg = *this->config_;
+ ACE_Configuration_Section_Key root;
+ int err = cfg.open_section (cfg.root_section (), SERVERS_ROOT_KEY, 0, root);
+ if (err != 0)
+ {
+ return 0; // Already gone.
+ }
+ ret = cfg.remove_section (root, name.c_str (), 1);
+ }
+ else if (rmode_ == Options::REPO_XML_FILE)
+ {
+ saveAsXML (this->fname_, *this);
+ }
+ return ret;
+}
+
+int
+Locator_Repository::remove_activator (const ACE_CString& name)
+{
+ int ret = activators().unbind (lcase(name));
+ if (ret != 0)
+ {
+ return ret;
+ }
+
+ if (rmode_ == Options::REPO_HEAP_FILE || rmode_ == Options::REPO_REGISTRY)
+ {
+ ACE_ASSERT (this->config_.get () != 0);
+ ACE_Configuration& cfg = *this->config_;
+ ACE_Configuration_Section_Key root;
+ int err = cfg.open_section (cfg.root_section (), ACTIVATORS_ROOT_KEY, 0, root);
+ if (err != 0)
+ {
+ return 0; // Already gone.
+ }
+ ret = cfg.remove_section (root, name.c_str (), 1);
+ }
+ else if (rmode_ == Options::REPO_XML_FILE)
+ {
+ saveAsXML (this->fname_, *this);
+ }
+ return ret;
+}
+
+Locator_Repository::SIMap&
+Locator_Repository::servers (void)
+{
+ return server_infos_;
+}
+
+Locator_Repository::AIMap&
+Locator_Repository::activators (void)
+{
+ return activator_infos_;
+}
+
+const char*
+Locator_Repository::repo_mode ()
+{
+ switch (rmode_)
+ {
+ case Options::REPO_XML_FILE:
+ case Options::REPO_HEAP_FILE:
+ return fname_.c_str ();
+ case Options::REPO_REGISTRY:
+ return "Registry";
+ case Options::REPO_NONE:
+ return "Disabled";
+ }
+ return "Disabled";
+}