summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp')
-rw-r--r--TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp514
1 files changed, 514 insertions, 0 deletions
diff --git a/TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp b/TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp
new file mode 100644
index 00000000000..0b01378ccf8
--- /dev/null
+++ b/TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp
@@ -0,0 +1,514 @@
+//$Id$
+#include "TestServer.h"
+
+#include "ManagerC.h"
+
+#include "tao/Profile.h"
+#include "tao/Stub.h"
+#include "tao/ORB_Core.h"
+#include "tao/PortableServer/Root_POA.h"
+
+#include "ace/streams.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/os_include/os_ctype.h"
+#include "ace/Get_Opt.h"
+
+#include <sstream>
+#include <utility>
+
+using std::string;
+
+// Does this function already exist?
+// Is there a path class?
+
+string normalizePath(const string& dir, char delim = '/', bool toLower = false);
+string getWorkingPath(char delim = '/', bool toLower = false);
+
+string deleteLeaf(const string& dir)
+{
+ string temp = dir;
+ temp.resize(dir.find_last_of("/\\"));
+ return temp;
+}
+
+string getWorkingPath(char delim, bool toLower)
+{
+ char buffer[PATH_MAX + 2];
+ ACE_OS::getcwd(buffer, PATH_MAX);
+ return normalizePath(buffer, delim, toLower);
+}
+
+string normalizePath(const string& dir, char delim, bool toLower)
+{
+ if (dir.empty() == true) return string();
+ char buffer[PATH_MAX + 2];
+
+ string::size_type i = 0;
+
+ for (; ACE_OS::ace_isspace(dir[i]); i++);
+
+ string::size_type begin = i;
+
+ int j = 0;
+ for (; i < dir.size(); i++)
+ {
+ if (dir[i] == '\\' || dir[i] == '/')
+ {
+ // skip redundant
+ if (dir[i + 1] == '\\' || dir[i + 1] == '/')
+ {
+ }
+ // Convert to proper delim
+ else
+ {
+ buffer[j] = delim; j++;
+ }
+ }
+ else if (dir[i] == '.')
+ {
+ // If specifying current, skip
+ if (dir[i + 1] == '\\' || dir[i + 1] == '/' || dir[i + 1] == '\0')
+ {
+ if (i == begin) // relative start
+ {
+ string curDir = getWorkingPath();
+ ACE_OS::strncpy(buffer, curDir.c_str(), sizeof(buffer));
+ j = curDir.length();
+ }
+ else
+ {
+ i += 2;
+ }
+ }
+ // If specifying parent, go back
+ else if (dir[i + 1] == '.')
+ {
+ if (i == begin) // relative start
+ {
+ string curDir = getWorkingPath();
+ ACE_OS::strncpy(buffer, curDir.c_str(), sizeof(buffer));
+ j = curDir.length();
+ }
+ int k = j;
+ for (; buffer[k] != delim; k--);
+ k--;
+ for (; buffer[k] != delim; k--);
+ j = (k + 1);
+ i+=2;
+ }
+ else
+ {
+ if (toLower)
+ buffer[j] = ::tolower(dir[i]);
+ else
+ buffer[j] = dir[i];
+ j++;
+ }
+ }
+ // normal character
+ else
+ {
+ if (toLower)
+ buffer[j] = ::tolower(dir[i]);
+ else
+ buffer[j] = dir[i];
+ j++;
+ }
+ }
+
+ if (buffer[j - 1] == delim) j--;
+ buffer[j] ='\0';
+ return string(buffer);
+}
+
+TestServer::TestServer(CORBA::ORB_ptr orb, int argc, char* argv[])
+: serverID_(1)
+, serverInstanceID_(-1)
+, useIORTable_(false)
+, writeIORFile_(false)
+, retryQuery_(false)
+, pauseType_('s')
+, startupPause_(0)
+, objActivatePause_(0)
+, activatePause_(0)
+, runPause_(0)
+, numPOAS_(0)
+, numObjsPerPOA_(0)
+, useItLoseItSecs_(0)
+, orb_(CORBA::ORB::_duplicate(orb))
+, iorTable_(IORTable::Table::_nil())
+, root_(PortableServer::POA::_nil())
+, mgr_(PortableServer::POAManager::_nil())
+{
+ parseCommands(argc, argv);
+
+ verifyEnvironment();
+
+ // We really do not want the current directory set by the
+ // activator. baseDir_ is where all the operation files are.
+ if (baseDir_.empty() == false)
+ {
+ ACE_OS::chdir(baseDir_.c_str());
+ }
+}
+
+TestServer::~TestServer()
+{
+ root_->destroy(1, 1);
+}
+
+// TestServer::parseCommands
+// Reads params from command line
+//
+int TestServer::parseCommands(int argc, char* argv[])
+{
+ ACE_Get_Opt get_opts(argc, argv, "w:e:d:t:o:s:c:a:r:p:n:x:z:q:b:");
+ int c;
+ while ((c = get_opts()) != -1)
+ {
+ switch (c)
+ {
+ case 'w':
+ expectedDir_ = normalizePath(get_opts.opt_arg());
+ break;
+
+ case 'e':
+ {
+ string name = get_opts.opt_arg();
+ string::size_type i = name.find_first_of("=");
+ string value = name.substr(i + 1, name.length() - 1);
+ name.resize(i);
+ expectedEnv_.push_back(std::make_pair(name, value));
+ break;
+ }
+
+ case 'd':
+ serverID_ = ACE_OS::atoi(get_opts.opt_arg());
+ break;
+
+ case 't':
+ {
+ const char* opt = get_opts.opt_arg();
+ useIORTable_ = (opt && opt[0] != '0');
+ break;
+ }
+
+ case 'q':
+ {
+ const char* opt = get_opts.opt_arg();
+ retryQuery_ = (opt && opt[0] != '0');
+ break;
+ }
+
+ case 'o':
+ {
+ const char* opt = get_opts.opt_arg();
+ writeIORFile_ = (opt && opt[0] != '0');
+ break;
+ }
+
+ case 's':
+ startupPause_ = ACE_OS::atoi(get_opts.opt_arg());
+ break;
+
+ case 'c':
+ objActivatePause_ = ACE_OS::atoi(get_opts.opt_arg());
+ break;
+
+ case 'a':
+ activatePause_ = ACE_OS::atoi(get_opts.opt_arg());
+ break;
+
+ case 'r':
+ runPause_ = ACE_OS::atoi(get_opts.opt_arg());
+ break;
+
+ case 'p':
+ numPOAS_ = ACE_OS::atoi(get_opts.opt_arg());
+ break;
+
+ case 'n':
+ numObjsPerPOA_ = ACE_OS::atoi(get_opts.opt_arg());
+ break;
+
+ case 'x':
+ useItLoseItSecs_ = ACE_OS::atoi(get_opts.opt_arg());
+ break;
+
+ case 'z':
+ pauseType_ = get_opts.opt_arg()[0];
+ break;
+
+ case 'b':
+ baseDir_ = get_opts.opt_arg();
+ break;
+
+ case '?':
+ default:
+ ACE_ERROR_RETURN((LM_ERROR,
+ "usage: %s\n"
+ "\t-d <startup pause in milliseconds>\n"
+ "\t-t 'use IOR Table'\n"
+ "\t-o 'write the IOR file'\n"
+ "\t-s <startup pause in milliseconds>\n"
+ "\t-a <activation pause in milliseconds>\n"
+ "\t-r <run pause in milliseconds>\n"
+ "\t-p <number of POAS>\n"
+ "\t-n <number of objects per POA>\n"
+ "\t-x <number of seconds from last hit till exit>\n"
+ "\t-e <expected_env_var_name>=<value> 'can be repeated'\n"
+ "\t-w <expected_working_directory>\n"
+ "\n",
+ argv[0]),
+ -1);
+ }
+ }
+ return 0;
+}
+
+// TestServer::verifyEnvironment
+// Checks to see if the activator setup requested env vars and current directory
+//
+bool TestServer::verifyEnvironment() const
+{
+ bool err = false;
+
+ // Check paths
+ string currentDir = getWorkingPath();
+ if (expectedDir_.empty() == false && currentDir != expectedDir_)
+ {
+ ACE_DEBUG((LM_DEBUG, "Error: directory paths (%s,%s) do not match.\n",
+ currentDir.c_str(), expectedDir_.c_str()));
+ err |= true;
+ }
+
+ // Check env vars
+ for (string::size_type i = 0; i < expectedEnv_.size(); i++)
+ {
+ const char* realValue = ACE_OS::getenv(expectedEnv_[i].first.c_str()) ;
+ if (realValue == NULL)
+ {
+ ACE_DEBUG((LM_DEBUG, "Error, env variable '%s' not found\n",
+ expectedEnv_[i].first.c_str()));
+ err |= true;
+ }
+ else if (expectedEnv_[i].second != realValue)
+ {
+ ACE_DEBUG((LM_DEBUG, "Error, env variable '%s' values (%s,%s) do not match.\n",
+ expectedEnv_[i].first.c_str(), realValue, expectedEnv_[i].second.c_str()));
+ err |= true;
+ }
+ }
+
+ return (err ? 1 : 0);
+}
+
+// TestServer::pause
+// Pause processing by either sleep or timed run-loop
+//
+void TestServer::pause(int milliseconds)
+{
+ if (milliseconds > 0)
+ {
+ if (pauseType_ == 's')
+ {
+ ACE_OS::sleep(ACE_Time_Value(0, milliseconds * 1000));
+ }
+ else if (pauseType_ == 'r')
+ {
+ ACE_Time_Value tv(0, milliseconds * 1000);
+ orb_->run(tv);
+ }
+ else
+ {
+ ACE_ASSERT(pauseType_ == 'r');
+ }
+ }
+}
+
+void TestServer::run()
+{
+ pause(startupPause_);
+
+ // FUZZ: disable check_for_missing_rir_env
+ CORBA::Object_var obj = orb_->resolve_initial_references("RootPOA");
+ root_ = PortableServer::POA::_narrow(obj.in());
+ mgr_ = root_->the_POAManager();
+
+ if (registerWithManager() == false)
+ return;
+
+ ACE_DEBUG((LM_DEBUG, "* Server (%d.%d) started.\n",
+ serverID_, serverInstanceID_));
+
+ if (useIORTable_ == true)
+ {
+ // FUZZ: disable check_for_missing_rir_env
+ CORBA::Object_var obj = orb_->resolve_initial_references("IORTable");
+ iorTable_ = IORTable::Table::_narrow(obj.in());
+ }
+
+ servant_.reset(new Messenger_i(orb_.in(), serverInstanceID_));
+
+ buildObjects();
+
+ pause(activatePause_);
+ mgr_->activate();
+
+ if (useItLoseItSecs_ > 0)
+ {
+ pause(runPause_);
+ do
+ {
+ ACE_Time_Value tv(useItLoseItSecs_);
+ orb_->run(tv);
+ } while (orb_->orb_core()->has_shutdown() == 0
+ && servant_->acknowledgeHit());
+ }
+
+ if (orb_->orb_core()->has_shutdown() != 0)
+ {
+ ACE_DEBUG((LM_DEBUG, "* Server (%d.%d) ended.\n",
+ serverID_, serverInstanceID_));
+ }
+ else
+ {
+ ACE_DEBUG((LM_DEBUG, "* Server (%d.%d) self terminated.\n",
+ serverID_, serverInstanceID_));
+ }
+}
+
+// TestServer::registerServer
+// This will register the server with the manager.
+//
+bool TestServer::registerWithManager()
+{
+ // So-far, the use cases dictate writting IOR
+ // responsibility is exclusive of registering
+ if (writeIORFile_ == false)
+ {
+ // Get the manager's ref
+ CORBA::Object_var obj = orb_->string_to_object("file://manager.ior");
+ if (CORBA::is_nil(obj.in()))
+ {
+ cerr << "Server Error: Could not get Manager IOR." << endl;
+ return false;
+ }
+ Manager_var manager = Manager::_narrow(obj.in());
+ if (CORBA::is_nil(manager.in())) {
+ cerr << "Server Error: IOR was not a Manager object reference." << endl;
+ return false;
+ }
+
+ // If this is a query process
+ if (retryQuery_ == true)
+ {
+ int diff = manager->endRetry();
+ if (diff != 0)
+ {
+ ACE_DEBUG((LM_DEBUG, "* Server Error: Not all retry attempts were made.\n"));
+ }
+ return false;
+ }
+ else // Get the server ID
+ {
+ serverInstanceID_ = manager->registerServer();
+ if (serverInstanceID_ == -1)
+ {
+ ACE_DEBUG((LM_DEBUG, "* Server (%d,%d) could not register.\n",
+ serverID_, serverInstanceID_));
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+// TestServer::buildObjects
+// Builds all the objects required by the client and server
+// Writes IORs if requested
+//
+void TestServer::buildObjects()
+{
+ // Append to existing file
+ ofstream iorFile("imr_test.ior", ios::app);
+
+ // Create number of requested POAS
+ for (int i = 0; i < numPOAS_; i++)
+ {
+ CORBA::PolicyList policies(3);
+ policies.length(3);
+ policies[0] = root_->create_id_assignment_policy(PortableServer::USER_ID);
+ policies[1] = root_->create_id_uniqueness_policy(PortableServer::MULTIPLE_ID);
+ policies[2] = root_->create_lifespan_policy(PortableServer::PERSISTENT);
+
+ // Create a POA
+ string poaName;
+ {
+ std::stringstream poaStream;
+ poaStream << "POA_" << serverID_ << "_" << (i + 1);
+ poaName = poaStream.str();
+ }
+
+ ACE_DEBUG((LM_DEBUG, "* Creating POA: %s\n", poaName.c_str()));
+
+ PortableServer::POA_var sub_poa = root_->create_POA(poaName.c_str(), mgr_.in(), policies);
+
+ pause(objActivatePause_);
+ // Create number of requested object references
+ for (int j = 0; j < numObjsPerPOA_; j++)
+ {
+ // Create object reference and activate it
+ string objName;
+ {
+ std::stringstream objStream;
+ objStream << "OBJ_" << serverID_ << "_" << (i + 1) << "_" << (j + 1);
+ objName = objStream.str();
+ }
+ ACE_DEBUG((LM_DEBUG, "* Activating Obj: %s\n", objName.c_str()));
+
+ PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId(objName.c_str());
+ sub_poa->activate_object_with_id(oid.in(), servant_.get());
+
+ // Output the stringified ID to the file for the client
+ if (! useIORTable_)
+ {
+ if (writeIORFile_)
+ {
+ // Write out IOR
+ CORBA::Object_var obj = sub_poa->id_to_reference(oid.in());
+ CORBA::String_var ior = orb_->object_to_string(obj.in());
+ iorFile << ior.in () << endl;
+ }
+ }
+ else // use IOR table
+ {
+ // Write out corbaloc
+ TAO_Root_POA* tmp_poa = dynamic_cast<TAO_Root_POA*>(sub_poa.in());
+ // Make entry into ior table using the non IMRified object ref.
+ CORBA::Object_var obj = tmp_poa->id_to_reference_i(oid.in(), false);
+ CORBA::String_var ior = orb_->object_to_string(obj.in());
+ string key = (poaName + "/" + objName);
+ iorTable_->bind(key.c_str(), ior.in());
+
+ if (writeIORFile_)
+ {
+ // Use the IMRified object ref to create the corbaloc.
+ CORBA::Object_var obj = sub_poa->id_to_reference(oid.in());
+
+ // Create a corbaloc
+ TAO_Profile* profile = obj->_stubobj()->profile_in_use();
+ CORBA::String_var temp = profile->to_string();
+ string corbaloc = temp.in();
+ corbaloc.resize(corbaloc.find_first_of(profile->object_key_delimiter()) + 1);
+ corbaloc += key;
+
+ // Write out corbaloc
+ iorFile << corbaloc.c_str() << endl;
+ }
+ }
+ }
+ }
+}