00001
00002
00003 #include "orbsvcs/PortableGroup/PG_Object_Group.h"
00004 #include "orbsvcs/PortableGroup/PG_conf.h"
00005
00006 #include "orbsvcs/PortableGroup/PG_Operators.h"
00007 #include "orbsvcs/PortableGroup/PG_Utils.h"
00008
00009 #include "tao/debug.h"
00010
00011 #include "ace/Get_Opt.h"
00012 #include "ace/Vector_T.h"
00013
00014
00015 #define TODO int todo;
00016
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018
00019 TAO::PG_Object_Group::MemberInfo::MemberInfo (
00020 CORBA::Object_ptr member,
00021 const PortableGroup::Location & location)
00022 : member_ (CORBA::Object::_duplicate (member))
00023 , factory_(PortableGroup::GenericFactory::_nil ())
00024 , location_ (location)
00025 , is_primary_ (0)
00026 {
00027 }
00028
00029 TAO::PG_Object_Group::MemberInfo::MemberInfo (
00030 CORBA::Object_ptr member,
00031 const PortableGroup::Location & location,
00032 PortableGroup::GenericFactory_ptr factory,
00033 PortableGroup::GenericFactory::FactoryCreationId factory_id)
00034 : member_ (CORBA::Object::_duplicate (member))
00035 , factory_ (PortableGroup::GenericFactory::_duplicate (factory))
00036 , factory_id_ (factory_id)
00037 , location_ (location)
00038 , is_primary_ (0)
00039 {
00040 }
00041
00042 TAO::PG_Object_Group::MemberInfo::~MemberInfo (void)
00043 {
00044 if( ! CORBA::is_nil (this->factory_.in()))
00045 {
00046 this->factory_->delete_object (this->factory_id_);
00047 }
00048 }
00049
00050
00051 TAO::PG_Object_Group::PG_Object_Group (
00052 CORBA::ORB_ptr orb,
00053 PortableGroup::FactoryRegistry_ptr factory_registry,
00054 TAO::PG_Object_Group_Manipulator & manipulator,
00055 CORBA::Object_ptr empty_group,
00056 const PortableGroup::TagGroupTaggedComponent & tagged_component,
00057 const char * type_id,
00058 const PortableGroup::Criteria & the_criteria,
00059 TAO::PG_Property_Set * type_properties)
00060 : internals_()
00061 , orb_ (CORBA::ORB::_duplicate (orb))
00062 , factory_registry_ (PortableGroup::FactoryRegistry::_duplicate (factory_registry))
00063 , manipulator_ (manipulator)
00064 , empty_ (1)
00065 , role_ (type_id)
00066 , type_id_ (CORBA::string_dup (type_id))
00067 , tagged_component_ (tagged_component)
00068 , reference_ (CORBA::Object::_duplicate(empty_group))
00069 , members_ ()
00070 , primary_location_(0)
00071 , properties_ (the_criteria, type_properties)
00072 , initial_number_members_ (0)
00073 , minimum_number_members_ (0)
00074 , group_specific_factories_ ()
00075 {
00076 }
00077
00078 TAO::PG_Object_Group::~PG_Object_Group (void)
00079 {
00080 for (MemberMap_Iterator it = this->members_.begin();
00081 it != this->members_.end();
00082 ++it)
00083 {
00084 MemberInfo * member = (*it).int_id_;
00085 delete member;
00086 }
00087 this->members_.unbind_all ();
00088 }
00089
00090 #if 0 // may want this again someday
00091
00092
00093 static void
00094 dump_ior (const char * base,
00095 const char * ext,
00096 unsigned long version,
00097 const char * iogr)
00098 {
00099 char filename[1000];
00100 ACE_OS::sprintf(filename, "%s_%lu.%s", base, version, ext );
00101
00102 FILE * iorfile = ACE_OS::fopen(filename, "w");
00103 ACE_OS::fwrite (iogr, 1, ACE_OS::strlen(iogr), iorfile);
00104 ACE_OS::fclose (iorfile);
00105 }
00106 #endif // may want this again someday
00107
00108 PortableGroup::ObjectGroup_ptr
00109 TAO::PG_Object_Group::reference (void) const
00110 {
00111 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00112 guard,
00113 this->internals_,
00114 PortableGroup::ObjectGroup::_nil ());
00115 return PortableGroup::ObjectGroup::_duplicate (this->reference_);
00116 }
00117
00118 void
00119 TAO::PG_Object_Group::get_group_specific_factories (
00120 PortableGroup::FactoryInfos & result) const
00121 {
00122 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00123
00124
00125
00126 result = this->group_specific_factories_;
00127 }
00128
00129 const PortableGroup::Location &
00130 TAO::PG_Object_Group::get_primary_location (void) const
00131 {
00132 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00133 guard,
00134 this->internals_,
00135 this->primary_location_);
00136 return this->primary_location_;
00137 }
00138
00139
00140 PortableGroup::ObjectGroup_ptr
00141 TAO::PG_Object_Group::add_member_to_iogr (CORBA::Object_ptr member)
00142 {
00143
00144
00145 PortableGroup::ObjectGroup_var result;
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 PortableGroup::ObjectGroup_var cleaned =
00158 PortableGroup::ObjectGroup::_duplicate (this->reference_.in ());
00159 if (this->empty_)
00160 {
00161
00162
00163 cleaned =
00164 this->manipulator_.remove_profiles (cleaned.in (),
00165 this->reference_.in ());
00166 this->empty_ = 0;
00167 }
00168
00169
00170 TAO_IOP::TAO_IOR_Manipulation::IORList iors (2);
00171 iors.length (2);
00172 iors [0] = CORBA::Object::_duplicate (cleaned.in());
00173 iors [1] = CORBA::Object::_duplicate (member);
00174
00175
00176 result =
00177 this->manipulator_.merge_iors (iors);
00178 return result._retn ();
00179 }
00180
00181 void
00182 TAO::PG_Object_Group::add_member (const PortableGroup::Location & the_location,
00183 CORBA::Object_ptr member)
00184
00185 {
00186 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00187
00188
00189
00190
00191
00192
00193
00194
00195 CORBA::String_var member_ior_string =
00196 orb_->object_to_string (member);
00197
00198 PortableGroup::ObjectGroup_var new_reference =
00199 add_member_to_iogr (member);
00200
00201
00202 CORBA::Object_var member_ior =
00203 this->orb_->string_to_object (member_ior_string.in ());
00204
00205 MemberInfo * info = 0;
00206 ACE_NEW_THROW_EX (info,
00207 MemberInfo (member_ior.in (),
00208 the_location),
00209 CORBA::NO_MEMORY());
00210
00211 if (this->members_.bind (the_location, info) != 0)
00212 {
00213
00214 throw CORBA::NO_MEMORY();
00215 }
00216
00217 this->reference_ = new_reference;
00218
00219 if (this->increment_version ())
00220 {
00221 this->distribute_iogr ();
00222 }
00223 else
00224 {
00225 throw PortableGroup::ObjectNotAdded ();
00226 }
00227
00228 if (TAO_debug_level > 6)
00229 {
00230 ACE_DEBUG ((LM_DEBUG,
00231 ACE_TEXT("PG (%P|%t) exit Object_Group add_member\n")));
00232 }
00233 }
00234
00235 int
00236 TAO::PG_Object_Group::set_primary_member (
00237 TAO_IOP::TAO_IOR_Property * prop,
00238 const PortableGroup::Location & the_location)
00239 {
00240 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00241 guard,
00242 this->internals_,
00243 0);
00244 int result = 1;
00245 MemberInfo * info = 0;
00246 if (this->members_.find (the_location, info) == 0)
00247 {
00248 int cleared = 0;
00249 this->primary_location_ = the_location;
00250 for (MemberMap_Iterator it = this->members_.begin();
00251 !cleared && it != this->members_.end();
00252 ++it)
00253 {
00254 cleared = (*it).int_id_->is_primary_;
00255 (*it).int_id_->is_primary_ = 0;
00256 }
00257 info->is_primary_ = 1;
00258
00259 int set_ok =
00260 this->manipulator_.set_primary (prop,
00261 this->reference_.in (),
00262 info->member_.in ());
00263 if (!set_ok)
00264 {
00265 if (TAO_debug_level > 3)
00266 {
00267 ACE_ERROR ((LM_ERROR,
00268 ACE_TEXT ("%T %n (%P|%t) - ")
00269 ACE_TEXT ("Can't set primary in IOGR .\n")
00270 ));
00271 }
00272
00273 result = 0;
00274 }
00275
00276 if (result && this->increment_version ())
00277 {
00278 this->distribute_iogr ();
00279 }
00280 else
00281 {
00282 if (TAO_debug_level > 3)
00283 {
00284 ACE_DEBUG ((LM_DEBUG,
00285 ACE_TEXT("TAO-PG (%P|%t) - set_primary_location ")
00286 ACE_TEXT("throwing PrimaryNotSet because increment")
00287 ACE_TEXT("version failed.\n")
00288 ));
00289 }
00290
00291 result = 0;
00292 }
00293 }
00294 else
00295 {
00296 if (TAO_debug_level > 3)
00297 {
00298 ACE_DEBUG ((LM_DEBUG,
00299 ACE_TEXT ("TAO-PG (%P|%t) - set_primary_location ")
00300 ACE_TEXT ("throwing MemberNotFound.\n")));
00301 }
00302 throw PortableGroup::MemberNotFound();
00303 }
00304
00305 return result;
00306 }
00307
00308
00309 void
00310 TAO::PG_Object_Group::remove_member (
00311 const PortableGroup::Location & the_location)
00312 {
00313 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00314 MemberInfo * info = 0;
00315 if (this->members_.unbind (the_location, info) == 0)
00316 {
00317 if (this->members_.current_size() > 0)
00318 {
00319 this->reference_ =
00320 this->manipulator_.remove_profiles (this->reference_.in (),
00321 info->member_.in ());
00322 }
00323 else
00324 {
00325 empty_ = 1;
00326 }
00327
00328 delete info;
00329
00330 if (the_location == this->primary_location_)
00331 {
00332 this->primary_location_.length(0);
00333 }
00334
00335 if (this->increment_version ())
00336 {
00337 this->distribute_iogr ();
00338 }
00339
00340 }
00341 else
00342 {
00343 if (TAO_debug_level > 6)
00344 {
00345 ACE_DEBUG ((LM_DEBUG,
00346 "TAO-PG (%P|%t) - "
00347 "remove_member throwing MemberNotFound.\n"
00348 ));
00349 }
00350 throw PortableGroup::MemberNotFound();
00351 }
00352 }
00353
00354
00355 PortableGroup::ObjectGroupId
00356 TAO::PG_Object_Group::get_object_group_id (void) const
00357 {
00358 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00359 guard,
00360 this->internals_,
00361 0);
00362 return this->tagged_component_.object_group_id;
00363 }
00364
00365 void
00366 TAO::PG_Object_Group::set_properties_dynamically (
00367 const PortableGroup::Properties & overrides)
00368 {
00369 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00370
00371 this->properties_.decode (overrides);
00372
00373
00374 }
00375
00376 void
00377 TAO::PG_Object_Group::get_properties (
00378 PortableGroup::Properties_var & result) const
00379 {
00380 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00381 this->properties_.export_properties(*result);
00382 }
00383
00384
00385 PortableGroup::TypeId
00386 TAO::PG_Object_Group::get_type_id (void) const
00387 {
00388 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00389 guard,
00390 this->internals_,
00391 0);
00392 return CORBA::string_dup (this->type_id_);
00393 }
00394
00395
00396
00397
00398
00399 int
00400 TAO::PG_Object_Group::increment_version (void)
00401 {
00402
00403 int result = 0;
00404 this->tagged_component_.object_group_ref_version += 1;
00405 if (TAO_debug_level > 3)
00406 {
00407 ACE_DEBUG ((LM_DEBUG,
00408 ACE_TEXT ("%T %n (%P|%t) - Setting IOGR version to %u\n"),
00409 static_cast<unsigned> (this->tagged_component_.object_group_ref_version)
00410 ));
00411 }
00412
00413
00414 if (TAO::PG_Utils::set_tagged_component (this->reference_,
00415 this->tagged_component_))
00416 {
00417 result = 1;
00418 }
00419 return result;
00420 }
00421
00422
00423
00424
00425 void
00426 TAO::PG_Object_Group::distribute_iogr (void)
00427 {
00428
00429 CORBA::String_var iogr =
00430 this->orb_->object_to_string (this->reference_.in());
00431
00432
00433 for (MemberMap_Iterator it = this->members_.begin();
00434 it != this->members_.end ();
00435 ++it)
00436 {
00437 MemberInfo const * info = (*it).int_id_;
00438
00439
00440
00441
00442
00443
00444
00445 PortableGroup::TAO_UpdateObjectGroup_var uog =
00446 PortableGroup::TAO_UpdateObjectGroup::_narrow ( info->member_.in ());
00447 if (!CORBA::is_nil (uog.in ()))
00448 {
00449 try
00450 {
00451 if (TAO_debug_level > 3)
00452 {
00453 ACE_DEBUG ((LM_DEBUG,
00454 "PG (%P|%t) - Object_Group pushing "
00455 "IOGR to %s member: %s@%s.\n",
00456 (info->is_primary_ ? "Primary" : "Backup"),
00457 this->role_.c_str (),
00458 static_cast<const char *> (info->location_[0].id)
00459 ));
00460 }
00461
00462
00463
00464 uog->tao_update_object_group (iogr.in (),
00465 this->tagged_component_.object_group_ref_version,
00466 info->is_primary_);
00467 }
00468 catch (const CORBA::Exception&)
00469 {
00470
00471
00472 }
00473 }
00474 else
00475 {
00476 ACE_ERROR ((LM_ERROR,
00477 "TAO::PG_Object_Group::distribute iogr can't "
00478 "narrow member reference to "
00479 "PortableGroup::TAO_UpdateObjectGroup.\n"
00480 ));
00481 }
00482 }
00483 }
00484
00485 PortableGroup::Locations *
00486 TAO::PG_Object_Group::locations_of_members (void)
00487 {
00488 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00489 guard,
00490 this->internals_,
00491 0);
00492
00493 PortableGroup::Locations * result = 0;
00494
00495 size_t count = this->members_.current_size ();
00496
00497 ACE_NEW_THROW_EX (
00498 result,
00499 PortableGroup::Locations (count),
00500 CORBA::NO_MEMORY() );
00501
00502 result->length (count);
00503
00504 size_t pos = 0;
00505 for (MemberMap_Iterator it = this->members_.begin();
00506 it != this->members_.end();
00507 ++it)
00508 {
00509 const PortableGroup::Location & location = (*it).ext_id_;
00510 PortableGroup::Location & out = (*result)[pos];
00511 out = location;
00512 }
00513 return result;
00514 }
00515
00516 CORBA::Object_ptr
00517 TAO::PG_Object_Group::get_member_reference (
00518 const PortableGroup::Location & the_location)
00519 {
00520 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00521 guard,
00522 this->internals_,
00523 CORBA::Object::_nil ());
00524
00525 CORBA::Object_var result;
00526
00527 MemberInfo * info = 0;
00528 if (this->members_.find (the_location, info) == 0)
00529 {
00530 result = CORBA::Object::_duplicate (info->member_.in ());
00531 }
00532 else
00533 {
00534 throw PortableGroup::MemberNotFound();
00535 }
00536 return result._retn ();
00537 }
00538
00539
00540 PortableGroup::MembershipStyleValue
00541 TAO::PG_Object_Group::get_membership_style (void) const
00542 {
00543 PortableGroup::MembershipStyleValue membership_style = 0;
00544 if (!TAO::find (properties_,
00545 PortableGroup::PG_MEMBERSHIP_STYLE,
00546 membership_style))
00547 {
00548 membership_style = TAO_PG_MEMBERSHIP_STYLE;
00549 }
00550 return membership_style;
00551 }
00552
00553
00554 PortableGroup::MinimumNumberMembersValue
00555 TAO::PG_Object_Group::get_minimum_number_members (void) const
00556 {
00557 PortableGroup::MinimumNumberMembersValue minimum_number_members = 0;
00558 if (!TAO::find (properties_,
00559 PortableGroup::PG_MINIMUM_NUMBER_MEMBERS,
00560 minimum_number_members))
00561 {
00562 minimum_number_members = TAO_PG_MINIMUM_NUMBER_MEMBERS;
00563 }
00564 return minimum_number_members;
00565 }
00566
00567 PortableGroup::InitialNumberMembersValue
00568 TAO::PG_Object_Group::get_initial_number_members (void) const
00569 {
00570 PortableGroup::InitialNumberMembersValue initial_number_members = 0;
00571 if (!TAO::find (properties_,
00572 PortableGroup::PG_INITIAL_NUMBER_MEMBERS,
00573 initial_number_members))
00574 {
00575 initial_number_members = TAO_PG_INITIAL_NUMBER_MEMBERS;
00576 }
00577 return initial_number_members;
00578 }
00579
00580 void
00581 TAO::PG_Object_Group::create_member (
00582 const PortableGroup::Location & the_location,
00583 const char * type_id,
00584 const PortableGroup::Criteria & the_criteria)
00585 {
00586 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00587
00588
00589 if (0 != this->members_.find (the_location))
00590 {
00591
00592
00593 CORBA::String_var factory_type;
00594 PortableGroup::FactoryInfos_var factories =
00595 this->factory_registry_->list_factories_by_role (
00596 role_.c_str(),
00597 factory_type.out ());
00598
00599
00600
00601 int created = 0;
00602 CORBA::ULong factory_count = factories->length ();
00603 for (CORBA::ULong factory_pos = 0;
00604 ! created && factory_pos < factory_count;
00605 ++factory_pos)
00606 {
00607 const PortableGroup::FactoryInfo & factory_info =
00608 (*factories)[factory_pos];
00609 if (factory_info.the_location == the_location)
00610 {
00611
00612
00613
00614 PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00615 CORBA::Object_var member =
00616 factory_info.the_factory->create_object (
00617 type_id,
00618 the_criteria,
00619 fcid. out());
00620
00621
00622
00623 CORBA::String_var member_ior_string =
00624 orb_->object_to_string (member.in ());
00625
00626 PortableGroup::ObjectGroup_var new_reference =
00627 this->add_member_to_iogr (member.in ());
00628
00629
00630 CORBA::Object_var member_ior =
00631 this->orb_->string_to_object (member_ior_string.in ());
00632
00633 MemberInfo * info = 0;
00634 ACE_NEW_THROW_EX (info, MemberInfo(
00635 member_ior.in(),
00636 the_location,
00637 factory_info.the_factory,
00638 fcid.in ()),
00639 CORBA::NO_MEMORY());
00640
00641 if (this->members_.bind (the_location, info) != 0)
00642 {
00643 throw CORBA::NO_MEMORY();
00644 }
00645
00646 this->reference_ = new_reference;
00647
00648
00649 if (this->increment_version ())
00650 {
00651 this->distribute_iogr ();
00652 }
00653 created = 1;
00654 }
00655 }
00656 if (! created)
00657 {
00658 throw PortableGroup::NoFactory ();
00659 }
00660 }
00661 else
00662 {
00663 throw PortableGroup::MemberAlreadyPresent ();
00664 }
00665 }
00666
00667 void
00668 TAO::PG_Object_Group::create_members (size_t count)
00669 {
00670
00671
00672
00673 CORBA::String_var factory_type;
00674 PortableGroup::FactoryInfos_var factories =
00675 this->factory_registry_->list_factories_by_role (
00676 role_.c_str(),
00677 factory_type.out ());
00678
00679 CORBA::ULong factory_count = factories->length ();
00680 if (factory_count > 0)
00681 {
00682 CORBA::ULong factory_pos = 0;
00683 while (members_.current_size () < count && factory_pos < factory_count)
00684 {
00685 const PortableGroup::FactoryInfo & factory_info =
00686 (*factories)[factory_pos];
00687 const PortableGroup::Location & factory_location =
00688 factory_info.the_location;
00689 if (0 != this->members_.find (factory_location))
00690 {
00691
00692
00693
00694 try
00695 {
00696 PortableGroup::GenericFactory::FactoryCreationId_var fcid;
00697 CORBA::Object_var member =
00698 factory_info.the_factory->create_object (
00699 this->type_id_.in (),
00700 factory_info.the_criteria,
00701 fcid. out());
00702
00703
00704
00705 CORBA::String_var member_ior_string =
00706 orb_->object_to_string (member.in ());
00707
00708 PortableGroup::ObjectGroup_var new_reference =
00709 this->add_member_to_iogr (member.in ());
00710
00711
00712 CORBA::Object_var member_ior =
00713 this->orb_->string_to_object (member_ior_string.in ());
00714
00715 MemberInfo * info = 0;
00716 ACE_NEW_THROW_EX (info, MemberInfo(
00717 member_ior.in(),
00718 factory_location,
00719 factory_info.the_factory,
00720 fcid.in ()),
00721 CORBA::NO_MEMORY());
00722
00723 if (this->members_.bind (factory_location, info) != 0)
00724 {
00725 throw CORBA::NO_MEMORY();
00726 }
00727 this->reference_ =
00728 new_reference;
00729
00730 }
00731 catch (const CORBA::Exception&)
00732 {
00733
00734 if (TAO_debug_level > 0)
00735 {
00736 ACE_ERROR ((LM_ERROR,
00737 ACE_TEXT ("PG (%P|%t) Replica Factory ")
00738 ACE_TEXT ("@ %s refused create_object ")
00739 ACE_TEXT ("request for type %s\n"),
00740 static_cast<const char *> (factory_info.the_location[0].id),
00741 static_cast<const char *> (this->type_id_.in ())
00742 ));
00743 }
00744 }
00745 }
00746 }
00747
00748 if (this->increment_version ())
00749 {
00750 this->distribute_iogr ();
00751 }
00752 }
00753 else
00754 {
00755 throw PortableGroup::NoFactory();
00756 }
00757 }
00758
00759 void
00760 TAO::PG_Object_Group::initial_populate (void)
00761 {
00762 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00763
00764 if (this->get_membership_style () == PortableGroup::MEMB_INF_CTRL)
00765 {
00766 PortableGroup::InitialNumberMembersValue initial_number_members =
00767 this->get_initial_number_members ();
00768
00769 if (this->members_.current_size () < initial_number_members)
00770 {
00771 this->create_members (initial_number_members);
00772 }
00773 }
00774 }
00775
00776 void
00777 TAO::PG_Object_Group::minimum_populate (void)
00778 {
00779 ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->internals_);
00780
00781 if ( this->get_membership_style () == PortableGroup::MEMB_INF_CTRL )
00782 {
00783 PortableGroup::MinimumNumberMembersValue minimum_number_members =
00784 this->get_minimum_number_members ();
00785 if (members_.current_size () < minimum_number_members)
00786 {
00787 this->create_members (minimum_number_members);
00788 }
00789 }
00790 }
00791
00792 int
00793 TAO::PG_Object_Group::has_member_at (const PortableGroup::Location & location)
00794 {
00795 return (0 == this->members_.find (location));
00796 }
00797
00798 TAO_END_VERSIONED_NAMESPACE_DECL
00799