| 1 | #include "PingPong.h"
 | 
|---|
 | 2 | #include "ariba/utility/configuration/Configuration.h"
 | 
|---|
 | 3 | 
 | 
|---|
 | 4 | using ariba::utility::Configuration;
 | 
|---|
 | 5 | using namespace ariba;
 | 
|---|
 | 6 | 
 | 
|---|
 | 7 | namespace ariba {
 | 
|---|
 | 8 | namespace application {
 | 
|---|
 | 9 | namespace pingpong {
 | 
|---|
 | 10 | 
 | 
|---|
 | 11 | // logging
 | 
|---|
 | 12 | use_logging_cpp( PingPong );
 | 
|---|
 | 13 | 
 | 
|---|
 | 14 | // the service that the pingpong wants to use
 | 
|---|
 | 15 | ServiceID PingPong::PINGPONG_SERVICEID = ServiceID( 111 );
 | 
|---|
 | 16 | 
 | 
|---|
 | 17 | // construction
 | 
|---|
 | 18 | PingPong::PingPong() : pingId( 0 ) {
 | 
|---|
 | 19 |         Timer::setInterval( 1000 );
 | 
|---|
 | 20 | }
 | 
|---|
 | 21 | 
 | 
|---|
 | 22 | // destruction
 | 
|---|
 | 23 | PingPong::~PingPong() {
 | 
|---|
 | 24 | }
 | 
|---|
 | 25 | 
 | 
|---|
 | 26 | // implementation of the startup interface
 | 
|---|
 | 27 | void PingPong::startup() {
 | 
|---|
 | 28 | 
 | 
|---|
 | 29 |         logging_info( "starting up PingPong service ... " );
 | 
|---|
 | 30 | 
 | 
|---|
 | 31 |         // create ariba module
 | 
|---|
 | 32 |         logging_debug( "creating ariba underlay module ... " );
 | 
|---|
 | 33 |         ariba = new AribaModule();
 | 
|---|
 | 34 | 
 | 
|---|
 | 35 |         Name spovnetName("pingpong");
 | 
|---|
 | 36 |         Name nodeName = Name::UNSPECIFIED;
 | 
|---|
 | 37 |         this->name = string("<ping>");
 | 
|---|
 | 38 | 
 | 
|---|
 | 39 |         // get settings from configuration object
 | 
|---|
 | 40 |         if( Configuration::haveConfig() ){
 | 
|---|
 | 41 |                 Configuration& config = Configuration::instance();
 | 
|---|
 | 42 | 
 | 
|---|
 | 43 |                 // get node name
 | 
|---|
 | 44 |                 if (config.exists("node.name"))
 | 
|---|
 | 45 |                         nodeName = config.read<string> ("node.name");
 | 
|---|
 | 46 | 
 | 
|---|
 | 47 |                 // configure ariba module
 | 
|---|
 | 48 |                 if (config.exists("ariba.endpoints"))
 | 
|---|
 | 49 |                         ariba->setProperty("endpoints", config.read<string>("ariba.endpoints"));
 | 
|---|
 | 50 |                 if (config.exists("ariba.bootstrap.hints"))
 | 
|---|
 | 51 |                         ariba->setProperty("bootstrap.hints", config.read<string>("ariba.bootstrap.hints"));
 | 
|---|
 | 52 |                 if (config.exists("pingpong.name"))
 | 
|---|
 | 53 |                         name = config.read<string>("pingpong.name");
 | 
|---|
 | 54 | 
 | 
|---|
 | 55 |         } // if( Configuration::haveConfig() )
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 |         // start ariba module
 | 
|---|
 | 58 |         ariba->start();
 | 
|---|
 | 59 | 
 | 
|---|
 | 60 |         // create node and join
 | 
|---|
 | 61 |         node = new Node( *ariba, nodeName );
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 |         // bind communication and node listener
 | 
|---|
 | 64 |         node->bind( this );                              /*NodeListener*/
 | 
|---|
 | 65 |         node->bind( this, PingPong::PINGPONG_SERVICEID); /*CommunicationListener*/
 | 
|---|
 | 66 | 
 | 
|---|
 | 67 |         // start node module
 | 
|---|
 | 68 |         node->start();
 | 
|---|
 | 69 | 
 | 
|---|
 | 70 |         // when initiating, you can define the overlay type, default is Chord [CHORD_OVERLAY]
 | 
|---|
 | 71 |         SpoVNetProperties params;
 | 
|---|
 | 72 |         //params.setBaseOverlayType( SpoVNetProperties::ONE_HOP_OVERLAY ); // alternative: OneHop
 | 
|---|
 | 73 | 
 | 
|---|
 | 74 |         // initiate the spovnet
 | 
|---|
 | 75 |         logging_info("initiating spovnet");
 | 
|---|
 | 76 |         node->initiate(spovnetName, params);
 | 
|---|
 | 77 | 
 | 
|---|
 | 78 |         // join the spovnet
 | 
|---|
 | 79 |         logging_info("joining spovnet");
 | 
|---|
 | 80 |         node->join(spovnetName);
 | 
|---|
 | 81 | 
 | 
|---|
 | 82 |         // ping pong started up...
 | 
|---|
 | 83 |         logging_info( "pingpong starting up with"
 | 
|---|
 | 84 |                         << " [spovnetid " << node->getSpoVNetId().toString() << "]"
 | 
|---|
 | 85 |                         << " and [nodeid " << node->getNodeId().toString() << "]" );
 | 
|---|
 | 86 | }
 | 
|---|
 | 87 | 
 | 
|---|
 | 88 | // implementation of the startup interface
 | 
|---|
 | 89 | void PingPong::shutdown() {
 | 
|---|
 | 90 | 
 | 
|---|
 | 91 |         logging_info( "pingpong service starting shutdown sequence ..." );
 | 
|---|
 | 92 | 
 | 
|---|
 | 93 |         // stop timer
 | 
|---|
 | 94 |         Timer::stop();
 | 
|---|
 | 95 | 
 | 
|---|
 | 96 |         // leave spovnet
 | 
|---|
 | 97 |         node->leave();
 | 
|---|
 | 98 | 
 | 
|---|
 | 99 |         // unbind communication and node listener
 | 
|---|
 | 100 |         node->unbind( this );                               /*NodeListener*/
 | 
|---|
 | 101 |         node->unbind( this, PingPong::PINGPONG_SERVICEID ); /*CommunicationListener*/
 | 
|---|
 | 102 | 
 | 
|---|
 | 103 |         // stop the ariba module
 | 
|---|
 | 104 |         ariba->stop();
 | 
|---|
 | 105 | 
 | 
|---|
 | 106 |         // delete node and ariba module
 | 
|---|
 | 107 |         delete node;
 | 
|---|
 | 108 |         delete ariba;
 | 
|---|
 | 109 | 
 | 
|---|
 | 110 |         // now we are completely shut down
 | 
|---|
 | 111 |         logging_info( "pingpong service shut down" );
 | 
|---|
 | 112 | }
 | 
|---|
 | 113 | 
 | 
|---|
 | 114 | // timer event
 | 
|---|
 | 115 | void PingPong::eventFunction() {
 | 
|---|
 | 116 | 
 | 
|---|
 | 117 |         // we ping all nodes that are known in the overlay structure
 | 
|---|
 | 118 |         // this can be all nodes (OneHop) overlay or just some neighbors
 | 
|---|
 | 119 |         // in case of a Chord or Kademlia structure
 | 
|---|
 | 120 | 
 | 
|---|
 | 121 |         // in this sample we use auto-links: we just send out our message
 | 
|---|
 | 122 |         // to the node and the link is established automatically. for more
 | 
|---|
 | 123 |         // control we would use the node->establishLink function to create
 | 
|---|
 | 124 |         // a link and start using the link in the CommunicationListener::onLinkUp
 | 
|---|
 | 125 |         // function that is implemented further down in PingPong::onLinkUp
 | 
|---|
 | 126 | 
 | 
|---|
 | 127 |         logging_info( "pinging overlay neighbors with ping id " << ++pingId );
 | 
|---|
 | 128 |         PingPongMessage pingmsg( pingId, name );
 | 
|---|
 | 129 | 
 | 
|---|
 | 130 |         //-----------------------------------------------------------------------
 | 
|---|
 | 131 |         // Option 1: get all neighboring nodes and send the message to each
 | 
|---|
 | 132 |         //-----------------------------------------------------------------------
 | 
|---|
 | 133 |         counter++;
 | 
|---|
 | 134 |         if (counter<0 || counter>4) {
 | 
|---|
 | 135 |                 counter = 0;
 | 
|---|
 | 136 |                 string s;
 | 
|---|
 | 137 |                 for (int i=0; i<names.size();i++) {
 | 
|---|
 | 138 |                         if (i!=0) s+= ", ";
 | 
|---|
 | 139 |                         s = s+names[i];
 | 
|---|
 | 140 |                 }
 | 
|---|
 | 141 |                 logging_info("----> I am " << name << " and I know " << s);
 | 
|---|
 | 142 |                 names.clear();
 | 
|---|
 | 143 |         }
 | 
|---|
 | 144 | 
 | 
|---|
 | 145 |         vector<NodeID> nodes = node->getNeighborNodes();
 | 
|---|
 | 146 |         BOOST_FOREACH( NodeID nid, nodes ){
 | 
|---|
 | 147 |                 logging_info( "sending ping message to " << nid.toString() );
 | 
|---|
 | 148 |                 node->sendMessage( pingmsg, nid, PingPong::PINGPONG_SERVICEID );
 | 
|---|
 | 149 |         }
 | 
|---|
 | 150 | 
 | 
|---|
 | 151 |         //-----------------------------------------------------------------------
 | 
|---|
 | 152 |         // Option 2: send a "broadcast message" that actually does the same thing
 | 
|---|
 | 153 |         //           internally, gets all neighboring nodes and sends the message
 | 
|---|
 | 154 |         //-----------------------------------------------------------------------
 | 
|---|
 | 155 |         // node->sendBroadcastMessage( pingmsg, PingPong::PINGPONG_SERVICEID );
 | 
|---|
 | 156 | }
 | 
|---|
 | 157 | 
 | 
|---|
 | 158 | void PingPong::onJoinCompleted( const SpoVNetID& vid ) {
 | 
|---|
 | 159 |         logging_info( "pingpong node join completed, spovnetid=" << vid.toString() );
 | 
|---|
 | 160 | 
 | 
|---|
 | 161 |         // start the timer to ping every second
 | 
|---|
 | 162 |         Timer::start();
 | 
|---|
 | 163 | }
 | 
|---|
 | 164 | 
 | 
|---|
 | 165 | void PingPong::onJoinFailed( const SpoVNetID& vid ) {
 | 
|---|
 | 166 |         logging_error("pingpong node join failed, spovnetid=" << vid.toString() );
 | 
|---|
 | 167 | }
 | 
|---|
 | 168 | 
 | 
|---|
 | 169 | void PingPong::onLeaveCompleted( const SpoVNetID& vid ){
 | 
|---|
 | 170 |         logging_info("pingpong node leave completed, spovnetid=" << vid.toString() );
 | 
|---|
 | 171 | }
 | 
|---|
 | 172 | 
 | 
|---|
 | 173 | void PingPong::onLeaveFailed( const SpoVNetID& vid ){
 | 
|---|
 | 174 |         logging_error("pingpong node leave failed, spovnetid=" << vid.toString() );
 | 
|---|
 | 175 | }
 | 
|---|
 | 176 | 
 | 
|---|
 | 177 | void PingPong::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk) {
 | 
|---|
 | 178 |         PingPongMessage* pingmsg = msg.getMessage()->convert<PingPongMessage> ();
 | 
|---|
 | 179 |         bool found=false;
 | 
|---|
 | 180 |         for (int i=0;i<names.size(); i++) if (names[i]==pingmsg->getName()) found=true;
 | 
|---|
 | 181 |         if (!found) names.push_back(pingmsg->getName());
 | 
|---|
 | 182 |         logging_info( "received ping message on link " << lnk.toString()
 | 
|---|
 | 183 |                         << " from node " << remote.toString()
 | 
|---|
 | 184 |                         << ": " << pingmsg->info() );
 | 
|---|
 | 185 | }
 | 
|---|
 | 186 | 
 | 
|---|
 | 187 | void PingPong::onLinkUp(const LinkID& lnk, const NodeID& remote){
 | 
|---|
 | 188 |         logging_info( "received link-up event for link " << lnk.toString()
 | 
|---|
 | 189 |                         << " and node " << remote.toString() );
 | 
|---|
 | 190 | }
 | 
|---|
 | 191 | 
 | 
|---|
 | 192 | void PingPong::onLinkDown(const LinkID& lnk, const NodeID& remote){
 | 
|---|
 | 193 |         logging_info( "received link-down event for link " << lnk.toString()
 | 
|---|
 | 194 |                         << " and node " << remote.toString() );
 | 
|---|
 | 195 | }
 | 
|---|
 | 196 | 
 | 
|---|
 | 197 | void PingPong::onLinkChanged(const LinkID& lnk, const NodeID& remote){
 | 
|---|
 | 198 |         logging_info( "link-changed event for link " << lnk.toString()
 | 
|---|
 | 199 |                         << " and node " << remote.toString() );
 | 
|---|
 | 200 | }
 | 
|---|
 | 201 | 
 | 
|---|
 | 202 | bool PingPong::onLinkRequest(const NodeID& remote, const DataMessage& msg) {
 | 
|---|
 | 203 |         logging_info( "node " << remote.toString() << " wants to build up a link with us ... allowing" );
 | 
|---|
 | 204 |         return true;
 | 
|---|
 | 205 | }
 | 
|---|
 | 206 | 
 | 
|---|
 | 207 | void PingPong::onLinkFail(const LinkID& lnk, const NodeID& remote){
 | 
|---|
 | 208 |         logging_info( "received link-failed event for link " << lnk.toString()
 | 
|---|
 | 209 |                         << " and node " << remote.toString() );
 | 
|---|
 | 210 | }
 | 
|---|
 | 211 | 
 | 
|---|
 | 212 | }}} // namespace ariba, application, pingpong
 | 
|---|