Go to the documentation of this file.00001 #ifndef _ACS_NOTIFICATION_SERVICE_MONITOR_H_
00002 #define _ACS_NOTIFICATION_SERVICE_MONITOR_H_
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 #ifndef __cplusplus
00031 #error This is a C++ include file and cannot be used from plain C
00032 #endif
00033
00034 #include <orbsvcs/CosNotifyChannelAdminS.h>
00035 #include <orbsvcs/CosNotifyCommC.h>
00036
00037
00038 #define GET_TIMESTAMP_NOW(X) \
00039 CORBA::ULongLong X; { \
00040 ACE_Time_Value const macro_now = ACE_OS::gettimeofday (); \
00041 X = \
00042 (static_cast<CORBA::ULongLong> (macro_now.sec ()) * (ACE_UINT32) 1000000 + \
00043 static_cast<CORBA::ULongLong> (macro_now.usec ())); \
00044 }
00045
00046 class PushSupplierImpl
00047 : public POA_CosNotifyComm::PushSupplier
00048 {
00049 virtual void disconnect_push_supplier(void) {}
00050 virtual void subscription_change(const CosNotification::EventTypeSeq&, const CosNotification::EventTypeSeq&) {}
00051 };
00052
00053 class PushConsumerImpl
00054 : public POA_CosNotifyComm::PushConsumer
00055 {
00056 public:
00057 PushConsumerImpl() : rtt(0) {};
00058 virtual void disconnect_push_consumer(void) {}
00059 virtual void offer_change(const CosNotification::EventTypeSeq&, const CosNotification::EventTypeSeq&) {}
00060 virtual void push(const CORBA::Any &data)
00061 {
00062 CORBA::ULongLong timestamp;
00063 data >>= timestamp;
00064 GET_TIMESTAMP_NOW(now);
00065 rtt = now - timestamp;
00066 }
00067
00068 CORBA::ULongLong getAndResetRTT()
00069 {
00070 CORBA::ULongLong retVal = rtt;
00071 rtt = 0;
00072 return retVal;
00073 };
00074
00075 private:
00076 CORBA::ULongLong rtt;
00077 };
00078
00079 class NotificationServiceMonitor
00080 {
00081 public:
00082 NotificationServiceMonitor(CosNotifyChannelAdmin::EventChannelFactory_ptr factory);
00083
00084 bool init(void);
00085 void destroy(void);
00086
00087 bool issuePingEvent(void);
00088
00089 CORBA::ULongLong getAndResetRTT() const { return pushConsumerImpl->getAndResetRTT(); };
00090 protected:
00091
00092 CosNotifyChannelAdmin::EventChannel_var ec_;
00093
00094
00095 PushSupplierImpl* pushSupplierImpl;
00096
00097
00098 PushConsumerImpl* pushConsumerImpl;
00099
00100
00101 CosNotifyChannelAdmin::ProxyPushConsumer_var proxyConsumer;
00102
00103
00104 CosNotifyChannelAdmin::EventChannelFactory_var notify_factory_;
00105
00106 };
00107
00108
00109 NotificationServiceMonitor::NotificationServiceMonitor(
00110 CosNotifyChannelAdmin::EventChannelFactory_ptr factory) :
00111 notify_factory_(CosNotifyChannelAdmin::EventChannelFactory::_duplicate(factory))
00112 {
00113 }
00114
00115 void
00116 NotificationServiceMonitor::destroy(void)
00117 {
00118 try
00119 {
00120 PortableServer::POA_var poa = pushConsumerImpl->_default_POA();
00121 PortableServer::ObjectId_var oid = poa->servant_to_id(pushConsumerImpl);
00122 poa->deactivate_object(oid.in());
00123 poa = pushSupplierImpl->_default_POA();
00124 oid = poa->servant_to_id(pushSupplierImpl);
00125 poa->deactivate_object(oid.in());
00126
00127 if (!CORBA::is_nil(ec_))
00128 ec_->destroy();
00129 } catch (...) {
00130
00131 }
00132 }
00133
00134 bool
00135 NotificationServiceMonitor::init (void)
00136 {
00137
00138
00139 CosNotifyChannelAdmin::ChannelID id;
00140 CosNotification::QoSProperties initial_qos;
00141 CosNotification::AdminProperties initial_admin;
00142 ec_ = notify_factory_->create_channel (initial_qos,
00143 initial_admin,
00144 id);
00145
00146
00147 CosNotifyChannelAdmin::AdminID supplier_admin_id;
00148 CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin_ =
00149 ec_->new_for_suppliers (CosNotifyChannelAdmin::OR_OP, supplier_admin_id);
00150
00151 if (CORBA::is_nil (supplier_admin_.in ()))
00152 return false;
00153
00154 CosNotifyChannelAdmin::AdminID consumer_admin_id;
00155 CosNotifyChannelAdmin::ConsumerAdmin_var consumer_admin_ =
00156 ec_->new_for_consumers (CosNotifyChannelAdmin::OR_OP, consumer_admin_id);
00157
00158 if (CORBA::is_nil (consumer_admin_.in ()))
00159 return false;
00160
00161
00162 CosNotifyChannelAdmin::ProxyID proxy_id;
00163 CosNotifyChannelAdmin::ProxySupplier_var ps =
00164 consumer_admin_->obtain_notification_push_supplier(
00165 CosNotifyChannelAdmin::ANY_EVENT,
00166 proxy_id);
00167
00168 CosNotifyChannelAdmin::ProxyPushSupplier_var anyps =
00169 CosNotifyChannelAdmin::ProxyPushSupplier::_narrow(ps.in());
00170
00171
00172 CosNotifyChannelAdmin::ProxyConsumer_var pc =
00173 supplier_admin_->obtain_notification_push_consumer(
00174 CosNotifyChannelAdmin::ANY_EVENT,
00175 proxy_id);
00176
00177 proxyConsumer =
00178 CosNotifyChannelAdmin::ProxyPushConsumer::_narrow(pc.in());
00179
00180
00181 pushSupplierImpl = new PushSupplierImpl();
00182 CosNotifyComm::PushSupplier_var pushSupplier = pushSupplierImpl->_this();
00183 pushSupplierImpl->_remove_ref();
00184 pushConsumerImpl = new PushConsumerImpl();
00185 CosNotifyComm::PushConsumer_var pushConsumer = pushConsumerImpl->_this();
00186 pushConsumerImpl->_remove_ref();
00187
00188 proxyConsumer->connect_any_push_supplier(pushSupplier.in());
00189 anyps->connect_any_push_consumer(pushConsumer.in());
00190
00191 return true;
00192 }
00193
00194 bool
00195 NotificationServiceMonitor::issuePingEvent()
00196 {
00197 if (CORBA::is_nil(proxyConsumer.in()))
00198 return false;
00199
00200 try
00201 {
00202 CORBA::Any data;
00203 GET_TIMESTAMP_NOW(ts);
00204 data <<= ts;
00205 proxyConsumer->push(data);
00206
00207 return true;
00208 }
00209 catch (...) {
00210 return false;
00211 }
00212 }
00213
00214 #endif