00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "orbsvcs/Notify/Reconnection_Registry.h"
00011
00012 #include "tao/debug.h"
00013 #include "orbsvcs/Notify/Properties.h"
00014 #include "orbsvcs/Notify/Topology_Saver.h"
00015 #include "ace/Vector_T.h"
00016
00017 #ifndef DEBUG_LEVEL
00018 # define DEBUG_LEVEL TAO_debug_level
00019 #endif
00020
00021
00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00023
00024 namespace TAO_Notify
00025 {
00026 const char REGISTRY_TYPE[] = "reconnect_registry";
00027 const char RECONNECT_ID[] = "ReconnectId";
00028 const char RECONNECT_IOR[] = "IOR";
00029 const char REGISTRY_CALLBACK_TYPE[] = "reconnect_callback";
00030
00031 Reconnection_Registry::Reconnection_Registry (Topology_Parent & parent)
00032 : highest_id_(0)
00033 {
00034
00035 Topology_Object::topology_parent_ = &parent;
00036 }
00037
00038 Reconnection_Registry::~Reconnection_Registry ()
00039 {
00040 }
00041
00042
00043
00044
00045 NotifyExt::ReconnectionRegistry::ReconnectionID
00046 Reconnection_Registry::register_callback (
00047 NotifyExt::ReconnectionCallback_ptr callback
00048 ACE_ENV_ARG_DECL)
00049 {
00050
00051 NotifyExt::ReconnectionRegistry::ReconnectionID next_id = ++highest_id_;
00052
00053 if (DEBUG_LEVEL > 0)
00054 {
00055 ACE_DEBUG ((LM_DEBUG,
00056 ACE_TEXT ("(%P|%t) Reconnect registry: registering %d\n"),
00057 static_cast<int> (next_id)
00058 ));
00059 }
00060 TAO_Notify_Properties* properties = TAO_Notify_PROPERTIES::instance();
00061 CORBA::ORB_var orb = properties->orb ();
00062
00063 CORBA::String_var cior = orb->object_to_string (callback ACE_ENV_ARG_PARAMETER);
00064 ACE_CHECK_RETURN (0);
00065 ACE_CString ior(cior.in ());
00066 if ( 0 != reconnection_registry_.bind (next_id, ior))
00067 {
00068
00069 }
00070 this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER);
00071 ACE_CHECK_RETURN (0);
00072
00073 return next_id;
00074 }
00075
00076 void
00077 Reconnection_Registry::unregister_callback (NotifyExt::ReconnectionRegistry::ReconnectionID id
00078 ACE_ENV_ARG_DECL)
00079 {
00080 if (DEBUG_LEVEL > 0)
00081 {
00082 ACE_DEBUG ((LM_DEBUG,
00083 ACE_TEXT ("(%P|%t) Reconnect registry: unregistering %d\n"),
00084 static_cast<int> (id)
00085 ));
00086 }
00087 if ( 0 != reconnection_registry_.unbind (id))
00088 {
00089
00090 }
00091 this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER);
00092 ACE_CHECK;
00093 }
00094
00095 CORBA::Boolean
00096 Reconnection_Registry::is_alive (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00097 {
00098 return CORBA::Boolean(1);
00099 }
00100
00101
00102
00103
00104 void
00105 Reconnection_Registry::save_persistent (Topology_Saver& saver ACE_ENV_ARG_DECL)
00106 {
00107 bool change = this->self_changed_;
00108 this->self_changed_ = false;
00109 this->children_changed_ = false;
00110
00111 NVPList attrs;
00112
00113 saver.begin_object (0, REGISTRY_TYPE, attrs, change ACE_ENV_ARG_PARAMETER);
00114 ACE_CHECK;
00115
00116 Reconnection_Registry_Type::ENTRY *entry;
00117 for (Reconnection_Registry_Type::ITERATOR iter (this->reconnection_registry_);
00118 iter.next (entry);
00119 iter.advance ())
00120 {
00121 NVPList cattrs;
00122 if (DEBUG_LEVEL > 0)
00123 {
00124 ACE_DEBUG ((LM_DEBUG,
00125 ACE_TEXT ("(%P|%t) Reconnect registry: saving %d\n"),
00126 static_cast<int> (entry->ext_id_)
00127 ));
00128 }
00129 cattrs.push_back(NVP(RECONNECT_ID, entry->ext_id_));
00130 cattrs.push_back(NVP(RECONNECT_IOR, entry->int_id_));
00131 saver.begin_object (entry->ext_id_, REGISTRY_CALLBACK_TYPE, cattrs, true ACE_ENV_ARG_PARAMETER);
00132 ACE_CHECK;
00133 saver.end_object (entry->ext_id_, REGISTRY_CALLBACK_TYPE ACE_ENV_ARG_PARAMETER);
00134 ACE_CHECK;
00135 }
00136
00137
00138
00139
00140
00141 saver.end_object (0, REGISTRY_TYPE ACE_ENV_ARG_PARAMETER);
00142 }
00143
00144
00145
00146
00147 Topology_Object*
00148 Reconnection_Registry::load_child (const ACE_CString & type,
00149 CORBA::Long,
00150 const NVPList& attrs
00151 ACE_ENV_ARG_DECL_NOT_USED)
00152 {
00153 if (type == REGISTRY_CALLBACK_TYPE)
00154 {
00155 NotifyExt::ReconnectionRegistry::ReconnectionID id;
00156 ACE_CString ior;
00157 if (attrs.load (RECONNECT_ID, id) && attrs.load (RECONNECT_IOR, ior))
00158 {
00159 if (id > highest_id_)
00160 {
00161 highest_id_ = id;
00162
00163 if (DEBUG_LEVEL > 0)
00164 {
00165 ACE_DEBUG ((LM_DEBUG,
00166 ACE_TEXT ("(%P|%t) Reconnect registry: reloading %d\n"),
00167 static_cast<int> (id)
00168 ));
00169 }
00170 }
00171 if ( 0 != reconnection_registry_.bind (id, ior))
00172 {
00173
00174 }
00175 }
00176 else
00177 {
00178 ACE_ERROR ((LM_ERROR,
00179 ACE_TEXT ("(%P|%t) Reconnect registry: missing attribute\n")
00180 ));
00181 }
00182 }
00183 return this;
00184 }
00185
00186 void
00187 Reconnection_Registry::send_reconnect (CosNotifyChannelAdmin::EventChannelFactory_ptr dest_factory
00188 ACE_ENV_ARG_DECL_NOT_USED)
00189 {
00190 TAO_Notify_Properties* properties = TAO_Notify_PROPERTIES::instance();
00191 CORBA::ORB_var orb = properties->orb ();
00192 ACE_Vector <NotifyExt::ReconnectionRegistry::ReconnectionID> bad_ids;
00193
00194 Reconnection_Registry_Type::ENTRY *entry;
00195 for (Reconnection_Registry_Type::ITERATOR iter (this->reconnection_registry_);
00196 iter.next (entry);
00197 iter.advance ())
00198 {
00199 ACE_DECLARE_NEW_ENV;
00200 ACE_TRY
00201 {
00202 if (DEBUG_LEVEL > 0)
00203 {
00204 ACE_DEBUG ((LM_DEBUG,
00205 ACE_TEXT ("(%P|%t) Reconnection Registry: Sending reconnection to client %d\n"),
00206 static_cast<int> (entry->ext_id_)
00207 ));
00208 }
00209 ACE_CString & ior = entry->int_id_;
00210 CORBA::Object_var obj = orb->string_to_object (ior.c_str () ACE_ENV_ARG_PARAMETER);
00211 ACE_TRY_CHECK;
00212 NotifyExt::ReconnectionCallback_var callback =
00213 NotifyExt::ReconnectionCallback::_narrow (obj.in ());
00214 if (!CORBA::is_nil (callback.in ()))
00215 {
00216 callback->reconnect (dest_factory ACE_ENV_ARG_PARAMETER);
00217 ACE_TRY_CHECK;
00218 }
00219 else
00220 {
00221 ACE_DEBUG ((LM_DEBUG,
00222 ACE_TEXT ("(%P|%t) Reconnection Registry: Can't resolve reconnection client's IOR %d\n"),
00223 static_cast<int> (entry->ext_id_)
00224 ));
00225
00226
00227 bad_ids.push_back (entry->ext_id_);
00228 }
00229 }
00230 ACE_CATCHANY
00231 {
00232 ACE_DEBUG ((LM_DEBUG,
00233 ACE_TEXT ("(%P|%t) Reconnection Registry: Exception sending reconnection to client -- discarding registry entry\n")
00234 ));
00235
00236 bad_ids.push_back (entry->ext_id_);
00237
00238 }
00239 ACE_ENDTRY;
00240 }
00241 size_t bad_count = bad_ids.size ();
00242 for (size_t nbad = 0; nbad < bad_count; ++nbad)
00243 {
00244 this->reconnection_registry_.unbind (bad_ids[nbad]);
00245 }
00246 }
00247
00248 void
00249 Reconnection_Registry::release (void)
00250 {
00251 delete this;
00252
00253 }
00254
00255 }
00256
00257 TAO_END_VERSIONED_NAMESPACE_DECL