1 #include "tao/ImR_Client/ImR_Client.h"
3 #include "ace/Vector_T.h"
5 #include "tao/ORB_Core.h"
7 #include "tao/Profile.h"
8 #include "tao/PortableServer/Root_POA.h"
9 #include "tao/PortableServer/Non_Servant_Upcall.h"
10 #include "tao/ImR_Client/ServerObject_i.h"
11 #include "tao/ImR_Client/ImplRepoC.h"
12 #include "tao/IORManipulation/IORManip_Loader.h"
15 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
19 char* find_delimiter (char* const ior
, const char delimiter
)
21 // Search for "corbaloc:" alone, without the protocol. This code
22 // should be protocol neutral.
23 const char corbaloc
[] = "corbaloc:";
24 char *pos
= ACE_OS::strstr (ior
, corbaloc
);
25 pos
= std::strchr (pos
+ sizeof (corbaloc
), ':');
26 pos
= std::strchr (pos
+ 1, delimiter
);
31 CORBA::Object_ptr
combine (TAO_ORB_Core
& orb_core
,
32 const TAO_Profile
& profile
,
33 const char* const key_str
,
36 CORBA::String_var profile_str
= profile
.to_string ();
38 if (TAO_debug_level
> 0)
40 TAOLIB_DEBUG ((LM_DEBUG
,
41 ACE_TEXT ("TAO_ImR_Client (%P|%t) - IMR partial IOR <%C>\n"),
44 char* const pos
= find_delimiter (profile_str
.inout (),
45 profile
.object_key_delimiter ());
47 pos
[1] = 0; // Crop the string.
50 if (TAO_debug_level
> 0)
52 TAOLIB_ERROR ((LM_ERROR
,
53 ACE_TEXT ("TAO_ImR_Client (%P|%t) - Could not parse ImR IOR, skipping ImRification\n")));
55 return CORBA::Object::_nil();
58 ACE_CString
ior (profile_str
.in ());
63 if (TAO_debug_level
> 0)
65 TAOLIB_DEBUG ((LM_DEBUG
,
66 ACE_TEXT ("TAO_ImR_Client (%P|%t) - ImR-ified IOR <%C>\n"),
69 CORBA::Object_ptr obj
= orb_core
.orb ()->string_to_object (ior
.c_str ());
70 obj
->_stubobj()->type_id
= type_id
;
77 ImRifyProfiles (const TAO_MProfile
& base_profiles
,
78 const TAO_Profile
* const profile_in_use
,
79 TAO_ORB_Core
& orb_core
,
80 const char* const key_str
,
82 : base_profiles_ (base_profiles
),
83 profile_in_use_ (profile_in_use
),
87 objs_ (base_profiles
.profile_count()),
88 list_buffer_ (new CORBA::Object_ptr
[base_profiles
.profile_count()]),
89 ior_list_ (base_profiles
.profile_count (),
90 base_profiles
.profile_count (),
96 ~ImRifyProfiles () { delete [] list_buffer_
; }
98 CORBA::Object_ptr
combined_ior ()
100 const CORBA::ULong pcount
= base_profiles_
.profile_count ();
101 for (CORBA::ULong i
= 0; i
< pcount
; ++i
)
103 if (!combine_profile (i
))
105 return default_obj ("could not resolve IORManipulation");
109 CORBA::Object_var IORM
= orb_core_
.orb ()
110 ->resolve_initial_references (TAO_OBJID_IORMANIPULATION
, 0);
112 if (CORBA::is_nil (IORM
.in ()))
114 return default_obj ("could not resolve IORManipulation");
117 TAO_IOP::TAO_IOR_Manipulation_var iorm
=
118 TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM
.in ());
120 if (CORBA::is_nil (iorm
.in ()))
122 return default_obj ("could not narrow IORManipulation");
127 return iorm
->merge_iors(ior_list_
);
129 catch (const ::CORBA::Exception
& )
131 return default_obj ("could not ImRify object with all profiles");
135 bool combine_profile(const CORBA::ULong i
)
139 // store the combined profile+key
140 list_buffer_
[i
] = combine (orb_core_
,
141 *(base_profiles_
.get_profile (i
)),
145 objs_
[i
] = list_buffer_
[i
];
149 catch (const ::CORBA::Exception
& )
155 CORBA::Object_ptr
default_obj(const char* desc
)
157 const CORBA::ULong pcount
= base_profiles_
.profile_count ();
158 const char* info
= "because couldn't find ImR profile_in_use in profiles";
160 // identify the profile in use to see if we can default to
161 // that profiles partial ImR-ification
162 for (CORBA::ULong i
= 0; i
< pcount
; ++i
)
164 if (profile_in_use_
== base_profiles_
.get_profile (i
))
166 // if there is no object then try one last time to combine
168 if (CORBA::is_nil(objs_
[i
].in ()) && !combine_profile (i
))
170 info
= "because couldn't ImR-ify profile_in_use";
174 if (TAO_debug_level
> 0)
176 TAOLIB_ERROR((LM_ERROR
,
177 ACE_TEXT("TAO_ImR_Client (%P|%t) - ERROR: %C. ")
178 ACE_TEXT("Defaulting to ImR-ifying profile_in_use\n"),
181 return objs_
[i
]._retn ();
185 if (TAO_debug_level
> 0)
187 TAOLIB_ERROR((LM_ERROR
,
188 ACE_TEXT ("TAO_ImR_Client (%P|%t) - ERROR: %C, ")
189 ACE_TEXT ("but cannot default to ImR-ifying profile_in_use %C\n"),
193 return CORBA::Object::_nil();
196 const TAO_MProfile
& base_profiles_
;
197 const TAO_Profile
* const profile_in_use_
;
198 TAO_ORB_Core
& orb_core_
;
199 const char* const key_str_
;
200 const char* const type_id_
;
201 ACE_Vector
<CORBA::Object_var
> objs_
;
202 CORBA::Object_ptr
* const list_buffer_
;
203 TAO_IOP::TAO_IOR_Manipulation::IORList ior_list_
;
211 ImR_Client_Adapter_Impl::ImR_Client_Adapter_Impl ()
217 ImR_Client_Adapter_Impl::imr_notify_startup (TAO_Root_POA
* poa
)
219 CORBA::Object_var imr
= poa
->orb_core ().implrepo_service ();
221 if (CORBA::is_nil (imr
.in ()))
223 if (TAO_debug_level
> 0)
225 TAOLIB_ERROR ((LM_ERROR
,
226 ACE_TEXT ("TAO_ImR_Client (%P|%t) - ERROR: No usable IMR initial reference ")
227 ACE_TEXT ("available but use IMR has been specified.\n")));
229 throw ::CORBA::TRANSIENT (
230 CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE
, 0),
231 CORBA::COMPLETED_NO
);
234 if (TAO_debug_level
> 0)
236 if (TAO_debug_level
> 1)
238 CORBA::ORB_ptr orb
= poa
->orb_core ().orb ();
239 CORBA::String_var ior
= orb
->object_to_string (imr
.in ());
240 TAOLIB_DEBUG ((LM_DEBUG
,
241 ACE_TEXT ("TAO_ImR_Client (%P|%t) - Notifying ImR of startup IMR IOR <%C>\n"),
246 ImplementationRepository::Administration_var imr_locator
;
249 // ATTENTION: Trick locking here, see class header for details
250 TAO::Portable_Server::Non_Servant_Upcall
non_servant_upcall (*poa
);
251 ACE_UNUSED_ARG (non_servant_upcall
);
254 ImplementationRepository::Administration::_narrow (imr
.in ());
257 if (CORBA::is_nil (imr_locator
.in ()))
259 if (TAO_debug_level
> 0)
261 TAOLIB_ERROR ((LM_ERROR
,
262 ACE_TEXT ("TAO_ImR_Client (%P|%t) - ERROR: Narrowed IMR initial reference ")
263 ACE_TEXT ("is nil but use IMR has been specified.\n")));
266 throw ::CORBA::TRANSIENT (
267 CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE
, 0),
268 CORBA::COMPLETED_NO
);
271 TAO_Root_POA
*root_poa
= poa
->object_adapter ().root_poa ();
272 ACE_NEW_THROW_EX (this->server_object_
,
273 ServerObject_i (poa
->orb_core ().orb (),
275 CORBA::NO_MEMORY ());
277 PortableServer::ServantBase_var
safe_servant (this->server_object_
);
278 ACE_UNUSED_ARG (safe_servant
);
280 // Since this method is called from the POA constructor, there
281 // shouldn't be any waiting required. Therefore,
282 // <wait_occurred_restart_call_ignored> can be ignored.
283 bool wait_occurred_restart_call_ignored
= false;
285 // Activate the servant in the root poa.
286 PortableServer::ObjectId_var id
=
287 root_poa
->activate_object_i (this->server_object_
,
288 poa
->server_priority (),
289 wait_occurred_restart_call_ignored
);
291 CORBA::Object_var obj
= root_poa
->id_to_reference_i (id
.in (), false);
293 ImplementationRepository::ServerObject_var svr
294 = ImplementationRepository::ServerObject::_narrow (obj
.in ());
296 if (!svr
->_stubobj () || !svr
->_stubobj ()->profile_in_use ())
298 if (TAO_debug_level
> 0)
300 TAOLIB_ERROR ((LM_ERROR
, "TAO_ImR_Client (%P|%t) - Invalid ImR ServerObject, bailing out.\n"));
304 CORBA::ORB_var orb
= root_poa
->_get_orb ();
305 CORBA::String_var full_ior
= orb
->object_to_string (obj
.in ());
306 TAO_Profile
& profile
= *(svr
->_stubobj ()->profile_in_use ());
307 CORBA::String_var ior
= profile
.to_string();
308 if (TAO_debug_level
> 0)
310 TAOLIB_DEBUG((LM_INFO
,
311 "TAO_ImR_Client (%P|%t) - full_ior <%C>\nior <%C>\n",
315 char* const pos
= find_delimiter (ior
.inout (),
316 profile
.object_key_delimiter ());
318 const ACE_CString
partial_ior (ior
.in (), (pos
- ior
.in ()) + 1);
320 if (TAO_debug_level
> 0)
322 CORBA::String_var poaname
= poa
->the_name ();
323 TAOLIB_DEBUG ((LM_DEBUG
,
324 ACE_TEXT ("TAO_ImR_Client (%P|%t) - Informing IMR that <%C> is running at <%C>\n"),
325 poaname
.in(), partial_ior
.c_str ()));
330 // ATTENTION: Trick locking here, see class header for details
331 TAO::Portable_Server::Non_Servant_Upcall
non_servant_upcall (*poa
);
332 ACE_UNUSED_ARG (non_servant_upcall
);
334 ACE_CString
const serverId
= poa
->orb_core ().server_id ();
336 if (serverId
.empty ())
342 name
= serverId
+ ":" + poa
->name ();
345 imr_locator
->server_is_running (name
.c_str (),
346 partial_ior
.c_str (),
349 catch (const ::CORBA::SystemException
&)
353 catch (const ::CORBA::Exception
&)
355 throw ::CORBA::TRANSIENT (
356 CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE
, 0),
357 CORBA::COMPLETED_NO
);
360 if (TAO_debug_level
> 0)
362 TAOLIB_DEBUG ((LM_DEBUG
,
363 ACE_TEXT ("TAO_ImR_Client (%P|%t) - Successfully notified ImR of Startup\n")));
368 ImR_Client_Adapter_Impl::imr_notify_shutdown (TAO_Root_POA
* poa
)
370 // Notify the Implementation Repository about shutting down.
371 CORBA::Object_var imr
= poa
->orb_core ().implrepo_service ();
373 // Check to see if there was an imr returned.
374 // If none, return ourselves.
375 if (CORBA::is_nil (imr
.in ()))
380 if (TAO_debug_level
> 0)
382 CORBA::String_var poaname
= poa
->the_name ();
383 TAOLIB_DEBUG ((LM_DEBUG
,
384 ACE_TEXT ("TAO_ImR_Client (%P|%t) - Notifying IMR of Shutdown server: <%C>\n"),
388 // ATTENTION: Trick locking here, see class header for details
389 TAO::Portable_Server::Non_Servant_Upcall
non_servant_upcall (*poa
);
390 ACE_UNUSED_ARG (non_servant_upcall
);
392 // Get the IMR's administrative object and call shutting_down on it
393 ImplementationRepository::Administration_var imr_locator
=
394 ImplementationRepository::Administration::_narrow (imr
.in ());
396 imr_locator
->server_is_shutting_down (poa
->name ().c_str ());
398 catch (const ::CORBA::COMM_FAILURE
&)
400 // At the moment we call this during ORB shutdown and the ORB is
401 // configured to drop replies during shutdown (it does by default in
402 // the LF model) we get a COMM_FAILURE exception which we ignore
403 if (TAO_debug_level
> 0)
405 TAOLIB_DEBUG ((LM_DEBUG
,
406 ACE_TEXT ("TAO_ImR_Client (%P|%t) - Ignoring COMM_FAILURE while unregistering")
407 ACE_TEXT ("from ImR.\n")));
410 catch (const ::CORBA::TRANSIENT
&)
412 // Similarly, there are cases where we could get a TRANSIENT.
413 if (TAO_debug_level
> 0)
415 TAOLIB_DEBUG ((LM_DEBUG
,
416 ACE_TEXT ("TAO_ImR_Client (%P|%t) - Ignoring TRANSIENT while unregistering")
417 ACE_TEXT ("from ImR.\n")));
420 catch (const ::CORBA::Exception
& ex
)
422 ex
._tao_print_exception (
423 "ImR_Client_Adapter_Impl::imr_notify_shutdown()");
427 if (this->server_object_
)
429 PortableServer::POA_var default_poa
=
430 this->server_object_
->_default_POA ();
432 TAO_Root_POA
*root_poa
=
433 dynamic_cast <TAO_Root_POA
*> (default_poa
.in ());
437 throw ::CORBA::OBJ_ADAPTER ();
440 PortableServer::ObjectId_var id
=
441 root_poa
->servant_to_id_i (this->server_object_
);
443 root_poa
->deactivate_object_i (id
.in ());
445 this->server_object_
= 0;
449 // *********************************************************************
451 // Initialization and registration of dynamic service object.
454 ImR_Client_Adapter_Impl::Initializer ()
456 TAO_Root_POA::imr_client_adapter_name (
457 "Concrete_ImR_Client_Adapter");
459 return ACE_Service_Config::process_directive (
460 ace_svc_desc_ImR_Client_Adapter_Impl
);
464 ImR_Client_Adapter_Impl::imr_key_to_object(TAO_Root_POA
* poa
,
465 const TAO::ObjectKey
&key
,
466 const char* type_id
) const
468 TAO_ORB_Core
& orb_core
= poa
->orb_core ();
469 // Check to see if we alter the IOR.
470 CORBA::Object_var imr
= orb_core
.implrepo_service ();
472 if (CORBA::is_nil (imr
.in ())
474 || !imr
->_stubobj ()->profile_in_use ())
476 if (TAO_debug_level
> 1)
478 TAOLIB_DEBUG ((LM_DEBUG
,
479 ACE_TEXT ("TAO_ImR_Client (%P|%t) - Missing ImR IOR, will not use the ImR\n")));
481 return CORBA::Object::_nil();
484 const TAO_MProfile
& base_profiles
= imr
->_stubobj ()->base_profiles ();
485 CORBA::String_var key_str
;
486 TAO::ObjectKey::encode_sequence_to_string (key_str
.inout (), key
);
488 // if there is only one profile, no need to use IORManipulation
489 if (base_profiles
.profile_count() == 1)
491 return combine(orb_core
,
492 *base_profiles
.get_profile(0),
497 // need to combine each profile in the ImR with the key and
498 // then merge them all together into one ImR-ified ior
499 ImRifyProfiles
imrify (base_profiles
,
500 imr
->_stubobj ()->profile_in_use (),
505 return imrify
.combined_ior ();
510 ACE_STATIC_SVC_DEFINE (
511 ImR_Client_Adapter_Impl
,
512 ACE_TEXT ("Concrete_ImR_Client_Adapter"),
514 &ACE_SVC_NAME (ImR_Client_Adapter_Impl
),
515 ACE_Service_Type::DELETE_THIS
| ACE_Service_Type::DELETE_OBJ
,
518 ACE_FACTORY_NAMESPACE_DEFINE (
520 ImR_Client_Adapter_Impl
,
521 TAO::ImR_Client::ImR_Client_Adapter_Impl
)
523 TAO_END_VERSIONED_NAMESPACE_DECL