Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / TAO / tao / ImR_Client / ImR_Client.cpp
blob4e6b3ad68916fd88cce43cb034f52585cb0f4f75
1 #include "tao/ImR_Client/ImR_Client.h"
3 #include "ace/Vector_T.h"
4 #include "tao/debug.h"
5 #include "tao/ORB_Core.h"
6 #include "tao/Stub.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"
13 #include <cstring>
15 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
17 namespace
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);
28 return pos;
31 CORBA::Object_ptr combine (TAO_ORB_Core& orb_core,
32 const TAO_Profile& profile,
33 const char* const key_str,
34 const char* type_id)
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"),
42 profile_str.in ()));
44 char* const pos = find_delimiter (profile_str.inout (),
45 profile.object_key_delimiter ());
46 if (pos)
47 pos[1] = 0; // Crop the string.
48 else
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 ());
60 // Add the key.
61 ior += key_str;
63 if (TAO_debug_level > 0)
65 TAOLIB_DEBUG ((LM_DEBUG,
66 ACE_TEXT ("TAO_ImR_Client (%P|%t) - ImR-ified IOR <%C>\n"),
67 ior.c_str ()));
69 CORBA::Object_ptr obj = orb_core.orb ()->string_to_object (ior.c_str ());
70 obj->_stubobj()->type_id = type_id;
71 return obj;
74 class ImRifyProfiles
76 public:
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,
81 const char* type_id)
82 : base_profiles_ (base_profiles),
83 profile_in_use_ (profile_in_use),
84 orb_core_ (orb_core),
85 key_str_ (key_str),
86 type_id_ (type_id),
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 (),
91 list_buffer_,
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");
134 private:
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)),
142 key_str_,
143 type_id_);
144 // manage the memory
145 objs_[i] = list_buffer_[i];
147 return true;
149 catch (const ::CORBA::Exception& )
151 return false;
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
167 // the profile
168 if (CORBA::is_nil(objs_[i].in ()) && !combine_profile (i))
170 info = "because couldn't ImR-ify profile_in_use";
171 break;
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"),
179 desc));
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"),
190 desc,
191 info));
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_;
207 namespace TAO
209 namespace ImR_Client
211 ImR_Client_Adapter_Impl::ImR_Client_Adapter_Impl ()
212 : server_object_ (0)
216 void
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"),
242 ior.in ()));
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);
253 imr_locator =
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 (),
274 root_poa),
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"));
302 return;
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",
312 full_ior.in(),
313 ior.in()));
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 ();
335 ACE_CString name;
336 if (serverId.empty ())
338 name = poa->name ();
340 else
342 name = serverId + ":" + poa->name ();
345 imr_locator->server_is_running (name.c_str (),
346 partial_ior.c_str (),
347 svr.in ());
349 catch (const ::CORBA::SystemException&)
351 throw;
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")));
367 void
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 ()))
376 return;
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"),
385 poaname.in ()));
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()");
424 // Ignore exceptions
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 ());
435 if (!root_poa)
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);
463 CORBA::Object_ptr
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 ())
473 || !imr->_stubobj ()
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),
493 key_str.in(),
494 type_id);
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 (),
501 orb_core,
502 key_str,
503 type_id);
505 return imrify.combined_ior ();
510 ACE_STATIC_SVC_DEFINE (
511 ImR_Client_Adapter_Impl,
512 ACE_TEXT ("Concrete_ImR_Client_Adapter"),
513 ACE_SVC_OBJ_T,
514 &ACE_SVC_NAME (ImR_Client_Adapter_Impl),
515 ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
518 ACE_FACTORY_NAMESPACE_DEFINE (
519 TAO_IMR_Client,
520 ImR_Client_Adapter_Impl,
521 TAO::ImR_Client::ImR_Client_Adapter_Impl)
523 TAO_END_VERSIONED_NAMESPACE_DECL