00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <tweek/tweekConfig.h>
00038
00039 #include <cstdio>
00040 #include <vpr/vpr.h>
00041
00042 #include <vpr/Util/Debug.h>
00043 #include <vpr/Util/Assert.h>
00044
00045 #include <tweek/Util/Version.h>
00046 #include <tweek/Util/Debug.h>
00047 #include <tweek/CORBA/SubjectManager.h>
00048 #include <tweek/CORBA/BeanDeliverySubjectImpl.h>
00049 #include <tweek/CORBA/CorbaHelpers.h>
00050 #include <tweek/CORBA/CorbaManager.h>
00051
00052
00053 namespace tweek
00054 {
00055
00056 const std::string CorbaManager::DELIVERY_SUBJECT_NAME("TweekBeanPusher");
00057
00058 CorbaManager::CorbaManager()
00059 : mAppName("unknown"), mOrbFunctor(NULL), mOrbThread(NULL),
00060 mSubjectManager(NULL), mBeanDeliverySubject(NULL)
00061 {
00062 std::string tweek_ver = getVersionString();
00063
00064
00065 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00066 << std::string(tweek_ver.length() + 14, '=') << std::endl
00067 << vprDEBUG_FLUSH;
00068 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00069 << clrOutNORM(clrGREEN, "Tweek Server: ") << clrOutNORM(clrGREEN, tweek_ver)
00070 << clrRESET << std::endl << vprDEBUG_FLUSH;
00071 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00072 << std::string(tweek_ver.length() + 14, '=') << std::endl
00073 << vprDEBUG_FLUSH;
00074 }
00075
00076 vpr::ReturnStatus CorbaManager::init(const std::string& local_id, int& argc,
00077 char** argv, const std::string& nsHost,
00078 const vpr::Uint16& nsPort,
00079 const std::string& iiopVersion)
00080 {
00081 vpr::ReturnStatus status;
00082
00083
00084 if ( NULL != argv )
00085 {
00086 mAppName = argv[0];
00087 }
00088
00089 try
00090 {
00091
00092 vprDEBUG(tweekDBG_CORBA, vprDBG_STATE_LVL)
00093 << "Initializing ORB (using init string '" << TWEEK_ORB_VER_STRING
00094 << "')\n" << vprDEBUG_FLUSH;
00095 mORB = CORBA::ORB_init(argc, argv, TWEEK_ORB_VER_STRING);
00096
00097 status = createChildPOA(local_id);
00098
00099 try
00100 {
00101
00102
00103
00104 if ( nsHost == std::string("") )
00105 {
00106 mRootContext = tweek::getRootNamingContextByInitRef(mORB);
00107 }
00108
00109
00110 else
00111 {
00112
00113 char nsPort_str[6];
00114 std::sprintf(nsPort_str, "%hu", nsPort);
00115
00116 std::string ns_uri("corbaloc:iiop:");
00117 ns_uri += iiopVersion;
00118 ns_uri += std::string("@");
00119 ns_uri += nsHost;
00120 ns_uri += std::string(":");
00121 ns_uri += nsPort_str;
00122 ns_uri += std::string("/NameService");
00123
00124 mRootContext = tweek::getRootNamingContextByURI(mORB, ns_uri);
00125 }
00126
00127 if ( ! CORBA::is_nil(mRootContext) )
00128 {
00129 mLocalContext = tweek::bindLocalNamingContext(mRootContext,
00130 std::string("tweek"));
00131
00132
00133 }
00134 }
00135 catch (CORBA::ORB::InvalidName& ex)
00136 {
00137 boost::ignore_unused_variable_warning(ex);
00138
00139
00140 vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00141 << "NameService name invalid in CorbaManager::init!\n"
00142 << vprDEBUG_FLUSH;
00143 }
00144
00145 vprDEBUG(tweekDBG_CORBA, vprDBG_STATE_LVL) << "Starting ORB thread\n"
00146 << vprDEBUG_FLUSH;
00147 mOrbFunctor = new vpr::ThreadRunFunctor<tweek::CorbaManager>(this);
00148 mOrbThread = new vpr::Thread(mOrbFunctor);
00149 }
00150 catch (CORBA::SystemException& sysEx)
00151 {
00152 status.setCode(vpr::ReturnStatus::Fail);
00153 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00154 << "Caught CORBA::SystemException during initialization\n"
00155 << vprDEBUG_FLUSH;
00156 vprDEBUG_NEXT(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00157 << "Mindor code: " << sysEx.minor() << ", completed: "
00158 << vprDEBUG_FLUSH;
00159
00160 switch ( sysEx.completed() )
00161 {
00162 case CORBA::COMPLETED_YES:
00163 vprDEBUG_CONT(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00164 << "YES" << std::endl << vprDEBUG_FLUSH;
00165 break;
00166 case CORBA::COMPLETED_NO:
00167 vprDEBUG_CONT(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00168 << "NO" << std::endl << vprDEBUG_FLUSH;
00169 break;
00170 case CORBA::COMPLETED_MAYBE:
00171 vprDEBUG_CONT(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00172 << "MAYBE" << std::endl << vprDEBUG_FLUSH;
00173 break;
00174 }
00175 }
00176 catch (CORBA::Exception&)
00177 {
00178 status.setCode(vpr::ReturnStatus::Fail);
00179 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00180 << "Caught CORBA::Exception during initialization.\n"
00181 << vprDEBUG_FLUSH;
00182 }
00183 catch (omniORB::fatalException& fe)
00184 {
00185 status.setCode(vpr::ReturnStatus::Fail);
00186 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00187 << "Caught omniORB::fatalException:\n" << vprDEBUG_FLUSH;
00188 vprDEBUG_NEXT(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00189 << " file: " << fe.file() << std::endl << vprDEBUG_FLUSH;
00190 vprDEBUG_NEXT(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00191 << " line: " << fe.line() << std::endl << vprDEBUG_FLUSH;
00192 vprDEBUG_NEXT(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00193 << " mesg: " << fe.errmsg() << std::endl << vprDEBUG_FLUSH;
00194 }
00195 catch(...)
00196 {
00197 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00198 << "Caught unknown exception during initialization." << std::endl
00199 << vprDEBUG_FLUSH;
00200 }
00201
00202 return status;
00203 }
00204
00205 void CorbaManager::shutdown(bool waitForCompletion)
00206 {
00207
00208
00209 if ( NULL != mSubjectManager )
00210 {
00211 if ( NULL != mBeanDeliverySubject )
00212 {
00213 mSubjectManager->unregisterSubject(DELIVERY_SUBJECT_NAME.c_str());
00214 delete mBeanDeliverySubject;
00215 }
00216
00217 destroySubjectManager();
00218 }
00219
00220 if ( ! CORBA::is_nil(mRootPOA) )
00221 {
00222
00223
00224
00225 mRootPOA->destroy(true, waitForCompletion);
00226 }
00227
00228 if ( ! CORBA::is_nil(mORB) )
00229 {
00230 try
00231 {
00232 mORB->shutdown(waitForCompletion);
00233 }
00234 catch (...)
00235 {
00236 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00237 << "Caught unknown exception during ORB shutdown." << std::endl
00238 << vprDEBUG_FLUSH;
00239 }
00240 }
00241 }
00242
00243 vpr::ReturnStatus CorbaManager::createSubjectManager()
00244 {
00245 vprASSERT(! CORBA::is_nil(mRootContext) && "No naming service available");
00246 vprASSERT(! CORBA::is_nil(mLocalContext) && "No naming service available");
00247 vpr::ReturnStatus status;
00248
00249 tweek::SubjectManager_ptr mgr_ptr;
00250
00251 vprASSERT(mSubjectManager == NULL && "Subject Manager already exists for this CORBA Manager!");
00252 mSubjectManager = new SubjectManagerImpl(*this);
00253 mSubjectManager->setApplicationName(mAppName);
00254
00255
00256
00257 try
00258 {
00259 mSubjectManagerId = mChildPOA->activate_object(mSubjectManager);
00260 }
00261
00262
00263 catch (PortableServer::POA::ServantAlreadyActive& active_ex)
00264 {
00265 boost::ignore_unused_variable_warning(active_ex);
00266 vprDEBUG(tweekDBG_CORBA, vprDBG_WARNING_LVL)
00267 << "WARNING: Servant already active within our POA\n"
00268 << vprDEBUG_FLUSH;
00269 }
00270 catch (PortableServer::POA::WrongPolicy& policy_ex)
00271 {
00272 boost::ignore_unused_variable_warning(policy_ex);
00273 status.setCode(vpr::ReturnStatus::Fail);
00274 vprDEBUG(tweekDBG_CORBA, vprDBG_CRITICAL_LVL)
00275 << "Invalid policy used when activating Subject Manager object\n"
00276 << vprDEBUG_FLUSH;
00277 }
00278
00279
00280
00281
00282 if ( status.success() )
00283 {
00284
00285
00286 try
00287 {
00288
00289
00290 std::string id_str("SubjectManager.");
00291 id_str += mSubjectManager->getGUID().toString();
00292 mSubjectManager->setName(id_str);
00293
00294 const char* kind = "Object";
00295
00296 vprDEBUG(tweekDBG_CORBA, vprDBG_VERB_LVL)
00297 << "Subject Manager ID: " << id_str << std::endl << vprDEBUG_FLUSH;
00298
00299
00300
00301
00302 mgr_ptr = mSubjectManager->_this();
00303
00304 vprASSERT(! CORBA::is_nil(mgr_ptr) && "CORBA object not activated in POA");
00305
00306 mSubjectManagerName.length(1);
00307 mSubjectManagerName[0].id = CORBA::string_dup(id_str.c_str());
00308 mSubjectManagerName[0].kind = CORBA::string_dup(kind);
00309
00310
00311
00312
00313
00314 try
00315 {
00316 mLocalContext->bind(mSubjectManagerName, mgr_ptr);
00317
00318
00319
00320
00321
00322 try
00323 {
00324 mBeanDeliverySubject = new BeanDeliverySubjectImpl();
00325 mSubjectManager->registerSubject(mBeanDeliverySubject,
00326 DELIVERY_SUBJECT_NAME.c_str());
00327 }
00328 catch (...)
00329 {
00330 delete mBeanDeliverySubject;
00331 vprDEBUG(tweekDBG_CORBA, vprDBG_WARNING_LVL)
00332 << clrOutNORM(clrYELLOW, "WARNING")
00333 << ": Failed to register Bean Delivery Subject\n"
00334 << vprDEBUG_FLUSH;
00335 }
00336 }
00337 catch (CosNaming::NamingContext::AlreadyBound& ex)
00338 {
00339 boost::ignore_unused_variable_warning(ex);
00340 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00341 << "WARNING: Subject manager reference already bound!\n"
00342 << vprDEBUG_FLUSH;
00343 }
00344 }
00345 catch (CORBA::COMM_FAILURE& ex)
00346 {
00347 boost::ignore_unused_variable_warning(ex);
00348 status.setCode(vpr::ReturnStatus::Fail);
00349 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00350 << "Unable to contact the naming service\n" << vprDEBUG_FLUSH;
00351 }
00352 catch (CORBA::SystemException&)
00353 {
00354 status.setCode(vpr::ReturnStatus::Fail);
00355 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00356 << "Caught a CORBA::SystemException while using the naming service"
00357 << std::endl << vprDEBUG_FLUSH;
00358 }
00359 }
00360
00361 return status;
00362 }
00363
00364 vpr::ReturnStatus CorbaManager::destroySubjectManager()
00365 {
00366 vpr::ReturnStatus status;
00367
00368
00369 if ( mSubjectManager != NULL )
00370 {
00371
00372
00373
00374 try
00375 {
00376
00377 mChildPOA->deactivate_object(mSubjectManagerId);
00378
00379
00380
00381
00382 try
00383 {
00384 mLocalContext->unbind(mSubjectManagerName);
00385 }
00386 catch (CORBA::ORB::InvalidName& ex)
00387 {
00388 boost::ignore_unused_variable_warning(ex);
00389 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00390 << "WARNING: Invalid name used when trying to unbind "
00391 << "Subject Manager!\n" << vprDEBUG_FLUSH;
00392 }
00393 catch (CosNaming::NamingContext::CannotProceed& ex)
00394 {
00395 boost::ignore_unused_variable_warning(ex);
00396 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00397 << "WARNING: Could not unbind Subject Manager!\n"
00398 << vprDEBUG_FLUSH;
00399 }
00400
00401
00402 delete mSubjectManager;
00403 mSubjectManager = NULL;
00404 }
00405 catch (PortableServer::POA::ObjectNotActive& policy_ex)
00406 {
00407 boost::ignore_unused_variable_warning(policy_ex);
00408
00409
00410
00411
00412
00413 delete mSubjectManager;
00414 mSubjectManager = NULL;
00415
00416 vprDEBUG(tweekDBG_CORBA, vprDBG_WARNING_LVL)
00417 << "WARNING: Coult not deactive Subject Manager: not active in POA\n"
00418 << vprDEBUG_FLUSH;
00419 }
00420 catch (PortableServer::POA::WrongPolicy& policy_ex)
00421 {
00422 boost::ignore_unused_variable_warning(policy_ex);
00423
00424 status.setCode(vpr::ReturnStatus::Fail);
00425 vprDEBUG(tweekDBG_CORBA, vprDBG_WARNING_LVL)
00426 << "WARNING: Coult not deactive Subject Manager: wrong POA policy\n"
00427 << vprDEBUG_FLUSH;
00428 }
00429 }
00430 else
00431 {
00432 status.setCode(vpr::ReturnStatus::Fail);
00433 vprDEBUG(tweekDBG_CORBA, vprDBG_WARNING_LVL)
00434 << "WARNING: No Subject Manager servant to destroy!\n"
00435 << vprDEBUG_FLUSH;
00436 }
00437
00438 return status;
00439 }
00440
00441
00442
00443
00444
00445 vpr::ReturnStatus CorbaManager::createChildPOA(const std::string& local_id)
00446 {
00447 vpr::ReturnStatus status;
00448 CORBA::Object_var obj;
00449 CORBA::PolicyList policy_list;
00450
00451
00452
00453 vprDEBUG(tweekDBG_CORBA, vprDBG_STATE_LVL) << "Requesting Root POA\n"
00454 << vprDEBUG_FLUSH;
00455 obj = mORB->resolve_initial_references("RootPOA");
00456 mRootPOA = PortableServer::POA::_narrow(obj);
00457
00458 vprASSERT(! CORBA::is_nil(mRootPOA) && "Failed to get Root POA");
00459
00460
00461
00462 PortableServer::IdUniquenessPolicy_var uniq_policy =
00463 mRootPOA->create_id_uniqueness_policy(PortableServer::MULTIPLE_ID);
00464 PortableServer::ServantRetentionPolicy_var retain_policy =
00465 mRootPOA->create_servant_retention_policy(PortableServer::RETAIN);
00466 PortableServer::ThreadPolicy_var thread_policy =
00467 mRootPOA->create_thread_policy(PortableServer::ORB_CTRL_MODEL);
00468
00469 policy_list.length(3);
00470 policy_list[0] =
00471 PortableServer::IdUniquenessPolicy::_duplicate(uniq_policy);
00472 policy_list[1] =
00473 PortableServer::ServantRetentionPolicy::_duplicate(retain_policy);
00474 policy_list[2] =
00475 PortableServer::ThreadPolicy::_duplicate(thread_policy);
00476
00477 std::string poa_name = "tweek_" + local_id;
00478
00479 try
00480 {
00481 vprDEBUG(tweekDBG_CORBA, vprDBG_STATE_LVL)
00482 << "Creating child of root POA named " << poa_name << std::endl
00483 << vprDEBUG_FLUSH;
00484 mChildPOA = mRootPOA->create_POA(poa_name.c_str(),
00485 PortableServer::POAManager::_nil(),
00486 policy_list);
00487 }
00488 catch (PortableServer::POA::AdapterAlreadyExists& ex)
00489 {
00490 boost::ignore_unused_variable_warning(ex);
00491 status.setCode(vpr::ReturnStatus::Fail);
00492 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00493 << "WARNING: Child POA named '" << poa_name << "' already exists!\n"
00494 << vprDEBUG_FLUSH;
00495 }
00496 catch (PortableServer::POA::InvalidPolicy& ex)
00497 {
00498 boost::ignore_unused_variable_warning(ex);
00499 status.setCode(vpr::ReturnStatus::Fail);
00500 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00501 << "WARNING: Failed to set IdUniquenessPolicy for child POA\n"
00502 << vprDEBUG_FLUSH;
00503 }
00504
00505 uniq_policy->destroy();
00506 retain_policy->destroy();
00507
00508 return status;
00509 }
00510
00511 void CorbaManager::run()
00512 {
00513 vprDEBUG(tweekDBG_CORBA, vprDBG_STATE_LVL) << "Server is running!\n"
00514 << vprDEBUG_FLUSH;
00515
00516 PortableServer::POAManager_var pman = mChildPOA->the_POAManager();
00517
00518 pman->activate();
00519 mORB->run();
00520
00521
00522 vprDEBUG(tweekDBG_CORBA, vprDBG_STATE_LVL) << "Server has shut down\n"
00523 << vprDEBUG_FLUSH;
00524 }
00525
00526 }