• Classes
  • Modules
  • Namespaces
  • Files
  • Related Pages
  • File List
  • File Members

acsNotificationServiceMonitor.h

Go to the documentation of this file.
00001 #ifndef _ACS_NOTIFICATION_SERVICE_MONITOR_H_
00002 #define _ACS_NOTIFICATION_SERVICE_MONITOR_H_
00003 
00004 /*******************************************************************************
00005 *    ALMA - Atacama Large Millimiter Array
00006 *    (c) European Southern Observatory, 2002
00007 *    Copyright by ESO (in the framework of the ALMA collaboration)
00008 *    and Cosylab 2002, All rights reserved
00009 *
00010 *    This library is free software; you can redistribute it and/or
00011 *    modify it under the terms of the GNU Lesser General Public
00012 *    License as published by the Free Software Foundation; either
00013 *    version 2.1 of the License, or (at your option) any later version.
00014 *
00015 *    This library is distributed in the hope that it will be useful,
00016 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 *    Lesser General Public License for more details.
00019 *
00020 *    You should have received a copy of the GNU Lesser General Public
00021 *    License along with this library; if not, write to the Free Software
00022 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00023 *
00024 * "@(#) $Id: acsNotificationServiceMonitor.h,v 1.1 2009/06/12 13:32:14 msekoran Exp $"
00025 *
00026 * who       when      what
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 // Carefully create the return value to avoid arithmetic overflow
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   // = Data Members
00092   CosNotifyChannelAdmin::EventChannel_var ec_;
00093   // The one channel that we create using the factory.
00094 
00095   PushSupplierImpl* pushSupplierImpl;
00096   // Supplier
00097 
00098   PushConsumerImpl* pushConsumerImpl;
00099   // Consumer
00100 
00101   CosNotifyChannelAdmin::ProxyPushConsumer_var proxyConsumer;
00102   // Proxy Consumer
00103 
00104   CosNotifyChannelAdmin::EventChannelFactory_var notify_factory_;
00105   // Channel factory.
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()); // this will also dispose the object itself
00123     poa = pushSupplierImpl->_default_POA();
00124     oid = poa->servant_to_id(pushSupplierImpl);
00125     poa->deactivate_object(oid.in()); // this will also dispose the object itself
00126     
00127     if (!CORBA::is_nil(ec_))
00128       ec_->destroy();
00129   } catch (...) {
00130     // noop (e.g. service might be down, etc.)
00131   }
00132 }
00133 
00134 bool
00135 NotificationServiceMonitor::init (void)
00136 {
00137   
00138   // Create channel...  
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   // Create admins...
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   // Connect a PushConsumer and PushSupplier
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

Generated on Thu Jan 12 2012 23:13:50 for ACS-10.0 C++ API by  doxygen 1.7.0