#include <BaseApp.h>
Inheritance diagram for BaseApp:
Base class for applications (Tier 1) that use overlay functionality. provides common API for structured overlays (KBR)
Public Member Functions | |
BaseApp () | |
virtual | ~BaseApp () |
virtual destructor | |
Protected Member Functions | |
int | numInitStages () const |
method to set InitStage | |
void | initialize (int stage) |
initializes base class-attributes | |
virtual void | initializeApp (int stage) |
initializes derived class-attributes | |
void | handleMessage (cMessage *msg) |
checks for message type and calls corresponding method | |
virtual void | receiveChangeNotification (int category, cPolymorphic *details) |
callback-method for events at the NotificationBoard | |
virtual void | handleTransportAddressChangedNotification () |
This method gets call if the node has a new TransportAddress (IP address) because he changed his access network. | |
virtual void | handleNodeLeaveNotification () |
This method gets call **.gracefulLeaveDelay seconds before it is killed. | |
virtual void | handleNodeGracefulLeaveNotification () |
This method gets call **.gracefulLeaveDelay seconds before it is killed if this node is among the gracefulLeaveProbability nodes. | |
void | finish () |
collects statistical data | |
virtual void | finishApp () |
collects statistical data of derived app | |
void | callRoute (const OverlayKey &key, cMessage *msg, const TransportAddress &hint=NodeHandle::UNSPECIFIED_NODE) |
Common API function: calls route-method in overlay. | |
void | callRouteDirect (const TransportAddress &dest, cMessage *msg) |
Common API function: calls route-method in overlay. | |
virtual void | deliver (OverlayKey &key, cMessage *msg) |
Common API function: handles delivered messages from overlay. | |
virtual void | forward (OverlayKey *key, cMessage **msg, NodeHandle *nextHopNode) |
Common API function: handles messages from overlay to be forwarded. | |
virtual void | update (const NodeHandle &node, bool joined) |
Common API function: informs application about neighbors and own nodeID. | |
NodeVector * | callLocalLookup (const OverlayKey &key, int num, bool safe) |
Common API function: produces a list of nodes that can be used as next hops towards key. | |
NodeVector * | callNeighborSet (int num) |
Common API function: produces a list of neighbor nodes. | |
bool | isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err) |
Query if a node is among the siblings for a given key. | |
virtual void | handleTimerEvent (cMessage *msg) |
processes self-messages | |
virtual void | handleAppMessage (cMessage *msg) |
method to handle non-commonAPI messages from the overlay | |
virtual void | handleUpperMessage (cMessage *msg) |
handleUpperMessage gets called of handleMessage(cMessage* msg) if msg arrivedOn from_upperTier (currently msg gets deleted in this function) | |
void | sendMessageToOverlay (cMessage *msg) |
sends non-commonAPI message to the overlay | |
void | sendRpcMessageToDestination (int destType, const TransportAddress &dest, const OverlayKey &destKey, BaseOverlayMessage *message) |
Protected Attributes | |
UnderlayConfigurator * | underlayConfigurator |
pointer to UnderlayConfigurator in this node | |
BootstrapOracle * | bootstrapOracle |
pointer to BootstrapOracle in this node | |
GlobalStatistics * | globalStatistics |
pointer to GlobalStatistics module in this node | |
NotificationBoard * | notificationBoard |
pointer to NotificationBoard in this node | |
BaseOverlay * | overlay |
pointer to the overlay module of this node | |
BaseApp * | tier1 |
BaseApp * | tier2 |
BaseApp * | tier3 |
bool | debugOutput |
debug output yes/no? | |
bool | onlyCommonAPIMessages |
process/send only commonAPI messages? | |
int | numSent |
number of sent packets | |
int | bytesSent |
number of sent bytes | |
int | numReceived |
number of received packets | |
int | bytesReceived |
number of received bytes | |
simtime_t | creationTime |
simTime when the App has been created | |
Private Member Functions | |
void | forwardResponse (const OverlayKey &key, cMessage *msg, const NodeHandle &nextHopNode) |
sends msg encapsulated in a KBRforward message to the overlay with destination key | |
void | handleCommonAPIMessage (CommonAPIMessage *commonAPIMsg) |
handles CommonAPIMessages |
BaseApp::BaseApp | ( | ) |
00035 { 00036 notificationBoard = NULL; 00037 00038 overlay = NULL; 00039 tier1 = NULL; 00040 tier2 = NULL; 00041 tier3 = NULL; 00042 }
BaseApp::~BaseApp | ( | ) | [virtual] |
void BaseApp::forwardResponse | ( | const OverlayKey & | key, | |
cMessage * | msg, | |||
const NodeHandle & | nextHopNode | |||
) | [private] |
sends msg encapsulated in a KBRforward message to the overlay with destination key
key | the destination OverlayKey | |
msg | the message to forward | |
nextHopNode | the considered next hop node on the route to the destination |
00262 { 00263 OverlayCtrlInfo* ctrlInfo = 00264 check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo()); 00265 00266 //create forwardResponse message (common API) 00267 KBRforward* forwardMsg = new KBRforward(); 00268 forwardMsg->setDestKey(key); 00269 forwardMsg->setNextHopNode(nextHopNode); 00270 forwardMsg->setControlInfo(ctrlInfo); 00271 forwardMsg->encapsulate(msg); 00272 00273 forwardMsg->setType(KBR_FORWARD_RESPONSE); 00274 00275 send(forwardMsg, "to_lowerTier"); 00276 }
void BaseApp::handleCommonAPIMessage | ( | CommonAPIMessage * | commonAPIMsg | ) | [private] |
handles CommonAPIMessages
This method gets called from BaseApp::handleMessage if message arrived from_lowerTier. It determines type of msg (KBR_DELIVER, KBR_FORWARD, KBR_UPDATE) and calls corresponding methods. All other messages are deleted.
commonAPIMsg | CommonAPIMessage |
00295 { 00296 cMessage* tempMsg = commonAPIMsg->decapsulate(); 00297 00298 // process interface control information 00299 OverlayCtrlInfo* overlayCtrlInfo = 00300 dynamic_cast<OverlayCtrlInfo*>(commonAPIMsg->removeControlInfo()); 00301 if(overlayCtrlInfo != NULL) { 00302 tempMsg->setControlInfo(overlayCtrlInfo); 00303 00304 if(debugOutput) 00305 EV << "[BaseApp::handleCommonAPIMessage() @ " << thisNode.ip 00306 << " (" << thisNode.key.toString(16) << ")]\n" 00307 << " Received message from node " << overlayCtrlInfo->getSrcNode().ip 00308 << endl; 00309 } 00310 00311 switch (commonAPIMsg->getType()) { 00312 00313 case KBR_DELIVER: 00314 { 00315 KBRdeliver* apiMsg = dynamic_cast<KBRdeliver*>(commonAPIMsg); 00316 OverlayKey key = apiMsg->getDestKey(); 00317 NodeHandle nextHopNode = thisNode; 00318 //first call forward, then deliver 00319 forward(&key, &tempMsg, &nextHopNode); 00320 00321 if(tempMsg != NULL) { 00322 //if key or nextHopNode is changed send msg back to overlay 00323 if ((!key.isUnspecified() && key != apiMsg->getDestKey()) || 00324 (!nextHopNode.isUnspecified() && 00325 nextHopNode != thisNode)) { 00326 forwardResponse(key, tempMsg, nextHopNode); 00327 } 00328 else { 00329 RECORD_STATS(numReceived++; bytesReceived += tempMsg->byteLength()); 00330 //handle RPC first 00331 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(tempMsg); 00332 if (rpcMessage!=NULL) { 00333 internalHandleRpcMessage(rpcMessage); 00334 } 00335 else { 00336 deliver(apiMsg->getDestKey(), tempMsg); 00337 } 00338 } 00339 } 00340 break; 00341 } 00342 00343 case KBR_FORWARD: 00344 { 00345 KBRforward* apiMsg = dynamic_cast<KBRforward*>(commonAPIMsg); 00346 OverlayKey key = apiMsg->getDestKey(); 00347 NodeHandle nextHopNode = apiMsg->getNextHopNode(); 00348 00349 forward(&key, &tempMsg, &nextHopNode); 00350 00351 //if message ist not deleted send it back 00352 if(tempMsg != NULL) { 00353 if(nextHopNode == apiMsg->getNextHopNode()) 00354 //do we need this? 00355 nextHopNode = NodeHandle::UNSPECIFIED_NODE; 00356 forwardResponse(key, tempMsg, nextHopNode); 00357 } 00358 break; 00359 } 00360 00361 case KBR_UPDATE: 00362 { 00363 KBRupdate* apiMsg = dynamic_cast<KBRupdate*>(commonAPIMsg); 00364 if(apiMsg->getJoined() && 00365 ((apiMsg->getNode().ip == thisNode.ip && 00366 (thisNode.port == -1 || apiMsg->getNode().port == thisNode.port)) || 00367 (!thisNode.key.isUnspecified() && apiMsg->getNode().key == thisNode.key))) 00368 thisNode = apiMsg->getNode(); 00369 else 00370 update(apiMsg->getNode(), apiMsg->getJoined()); 00371 00372 break; 00373 } 00374 00375 default: 00376 { 00377 delete tempMsg; 00378 } 00379 } 00380 delete commonAPIMsg; 00381 }
int BaseApp::numInitStages | ( | ) | const [protected] |
method to set InitStage
Reimplemented in DHTTestApp, and DHTXMLRealworldApp.
00050 { 00051 return MAX_STAGE_APP + 1; 00052 }
void BaseApp::initialize | ( | int | stage | ) | [protected] |
initializes base class-attributes
stage | the init stage |
Reimplemented in DHTTestApp, and DHTXMLRealworldApp.
00055 { 00056 if(stage == MIN_STAGE_APP) { 00057 // fetch parameters 00058 debugOutput = par("debugOutput"); 00059 onlyCommonAPIMessages = true; 00060 00061 bootstrapOracle = BootstrapOracleAccess().get(); 00062 underlayConfigurator = UnderlayConfiguratorAccess().get(); 00063 globalStatistics = GlobalStatisticsAccess().get(); 00064 notificationBoard = NotificationBoardAccess().get(); 00065 00066 // subscribe to the notification board 00067 notificationBoard->subscribe(this, NF_OVERLAY_TRANSPORTADDRESS_CHANGED); 00068 notificationBoard->subscribe(this, NF_OVERLAY_NODE_LEAVE); 00069 notificationBoard->subscribe(this, NF_OVERLAY_NODE_GRACEFUL_LEAVE); 00070 00071 // set overlay and tier pointers 00072 cModule* temp = this; 00073 do { 00074 temp = temp->gate("to_lowerTier")->destinationGate()->ownerModule(); 00075 overlay = dynamic_cast<BaseOverlay*>(temp); 00076 } while(overlay == NULL); 00077 00078 tier1 = dynamic_cast<BaseApp*>(overlay->gate("to_app") 00079 ->destinationGate()->ownerModule()); 00080 if(tier1 != NULL && tier1->gate("to_upperTier") != NULL) { 00081 cGate* temp = tier1->gate("to_upperTier")->destinationGate(); 00082 if(temp != NULL) { 00083 tier2 = dynamic_cast<BaseApp*>(temp->ownerModule()); 00084 if(tier2 != NULL && tier2->gate("to_upperTier") != NULL) { 00085 cGate* temp = tier2->gate("to_upperTier")->destinationGate(); 00086 if(temp != NULL) { 00087 tier3 = dynamic_cast<BaseApp*>(temp->ownerModule()); 00088 } 00089 } 00090 } 00091 } 00092 00093 // determine the terminal's transport address 00094 thisNode.ip = IPAddressResolver().addressOf(parentModule()->parentModule()).get4(); 00095 WATCH(thisNode); 00096 00097 // statistics 00098 numSent = 0; 00099 numReceived = 0; 00100 bytesSent = 0; 00101 bytesReceived = 0; 00102 creationTime = simTime(); 00103 00104 WATCH(numSent); 00105 WATCH(numReceived); 00106 WATCH(bytesSent); 00107 WATCH(bytesReceived); 00108 } 00109 00110 00111 00112 if(stage >= MIN_STAGE_APP && stage <= MAX_STAGE_APP) 00113 initializeApp(stage); 00114 00115 // init rpcs 00116 initRpcs(); 00117 }
void BaseApp::initializeApp | ( | int | stage | ) | [protected, virtual] |
initializes derived class-attributes
stage | the init stage |
Reimplemented in DHT, GIASearchApp, KBRTestApp, RealWorldTestApp, and SimpleClient.
void BaseApp::handleMessage | ( | cMessage * | msg | ) | [protected] |
checks for message type and calls corresponding method
checks for message type (from overlay or selfmessage) and calls corresponding method like deliver(), forward(), and timer()
msg | the handled message |
Reimplemented in DHTXMLRealworldApp.
00126 { 00127 // Process self-messages. 00128 if(msg->isSelfMessage()) { 00129 // process rpc self-messages 00130 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg); 00131 if (rpcMessage!=NULL) { 00132 internalHandleRpcMessage(rpcMessage); 00133 return; 00134 } 00135 // process all other self-messages 00136 handleTimerEvent(msg); 00137 return; 00138 } 00139 00140 if(msg->arrivedOn("from_lowerTier")) { 00141 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg); 00142 if (rpcMessage!=NULL) { 00143 internalHandleRpcMessage(rpcMessage); 00144 return; 00145 } 00146 // common API 00147 CommonAPIMessage* commonAPIMsg = dynamic_cast<CommonAPIMessage*>(msg); 00148 if(commonAPIMsg != NULL) 00149 handleCommonAPIMessage(commonAPIMsg); 00150 00151 else if (onlyCommonAPIMessages == false) { 00152 RECORD_STATS(numReceived++; bytesReceived += msg->byteLength()); 00153 handleAppMessage(msg); 00154 } 00155 else 00156 delete msg; 00157 } 00158 else if(msg->arrivedOn("from_upperTier")) { 00159 BaseRpcMessage* rpcMessage = dynamic_cast<BaseRpcMessage*>(msg); 00160 if (rpcMessage!=NULL) { 00161 internalHandleRpcMessage(rpcMessage); 00162 return; 00163 } 00164 handleUpperMessage(msg); 00165 } 00166 }
void BaseApp::receiveChangeNotification | ( | int | category, | |
cPolymorphic * | details | |||
) | [protected, virtual] |
callback-method for events at the NotificationBoard
category | ... TODO ... | |
details | ... TODO ... |
00174 { 00175 Enter_Method_Silent(); 00176 if (category == NF_OVERLAY_TRANSPORTADDRESS_CHANGED) { 00177 handleTransportAddressChangedNotification(); 00178 } else if (category == NF_OVERLAY_NODE_LEAVE) { 00179 handleNodeLeaveNotification(); 00180 } else if (category == NF_OVERLAY_TRANSPORTADDRESS_CHANGED) { 00181 handleNodeGracefulLeaveNotification(); 00182 } 00183 }
void BaseApp::handleTransportAddressChangedNotification | ( | ) | [protected, virtual] |
This method gets call if the node has a new TransportAddress (IP address) because he changed his access network.
void BaseApp::handleNodeLeaveNotification | ( | ) | [protected, virtual] |
This method gets call **.gracefulLeaveDelay seconds before it is killed.
Reimplemented in KBRTestApp.
void BaseApp::handleNodeGracefulLeaveNotification | ( | ) | [protected, virtual] |
void BaseApp::finish | ( | ) | [protected] |
collects statistical data
Reimplemented in DHTTestApp.
00401 { 00402 finishRpcs(); 00403 00404 // record scalar data 00405 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 00406 00407 if(time != 0) { 00408 globalStatistics->addStdDev("BaseApp: Sent Messages/s", numSent / time); 00409 globalStatistics->addStdDev("BaseApp: Received Messages/s", numReceived / time); 00410 globalStatistics->addStdDev("BaseApp: Sent Bytes/s", bytesSent / time); 00411 globalStatistics->addStdDev("BaseApp: Received Bytes/s", bytesReceived / time); 00412 } 00413 00414 finishApp(); 00415 }
void BaseApp::finishApp | ( | ) | [protected, virtual] |
collects statistical data of derived app
Reimplemented in DHT, GIASearchApp, KBRTestApp, and RealWorldTestApp.
void BaseApp::callRoute | ( | const OverlayKey & | key, | |
cMessage * | msg, | |||
const TransportAddress & | hint = NodeHandle::UNSPECIFIED_NODE | |||
) | [protected] |
Common API function: calls route-method in overlay.
encapsulates msg into KBRroute message and sends it to the overlay module
key | destination key | |
msg | message to route | |
hint | next hop (usually unused) |
00202 { 00203 // create route-message (common API) 00204 KBRroute* routeMsg = new KBRroute(); 00205 routeMsg->setDestKey(key); 00206 routeMsg->setHint(hint); 00207 routeMsg->encapsulate(msg); 00208 00209 routeMsg->setType(KBR_ROUTE); 00210 00211 send(routeMsg, "to_lowerTier"); 00212 00213 // debug output 00214 if (debugOutput) 00215 EV << "[BaseApp::callRoute() @ " << thisNode.ip 00216 << " (" << thisNode.key.toString(16) << ")]\n" 00217 << " Sent message " << id() << "-" << numSent << "\n" 00218 << " to destination key " << key.toString(16) 00219 << endl; 00220 00221 // count 00222 RECORD_STATS(numSent++; bytesSent += msg->byteLength()); 00223 }
void BaseApp::callRouteDirect | ( | const TransportAddress & | dest, | |
cMessage * | msg | |||
) | [protected] |
Common API function: calls route-method in overlay.
encapsulates msg into KBRrouteDirect message and sends it to the overlay module
dest | destination transport address | |
msg | message to route |
00226 { 00227 // create route-message (common API) 00228 KBRrouteDirect* routeMsg = new KBRrouteDirect(); 00229 routeMsg->setDest(dest); 00230 routeMsg->encapsulate(msg); 00231 00232 routeMsg->setType(KBR_ROUTEDIRECT); 00233 00234 send(routeMsg, "to_lowerTier"); 00235 00236 // debug output 00237 if (debugOutput) 00238 EV << "[BaseApp::callRouteDirect() @ " << thisNode.ip 00239 << " (" << thisNode.key.toString(16) << ")]\n" 00240 << " Sent message " << id() << "-" << numSent << "\n" 00241 << " to destination " << dest 00242 << endl; 00243 00244 // count 00245 RECORD_STATS(numSent++; bytesSent += msg->byteLength()); 00246 }
void BaseApp::deliver | ( | OverlayKey & | key, | |
cMessage * | msg | |||
) | [protected, virtual] |
Common API function: handles delivered messages from overlay.
method to handle decapsulated KBRdeliver messages from overlay module, should be overwritten in derived application
key | destination key | |
msg | delivered message |
Reimplemented in KBRTestApp, and RealWorldTestApp.
void BaseApp::forward | ( | OverlayKey * | key, | |
cMessage ** | msg, | |||
NodeHandle * | nextHopNode | |||
) | [protected, virtual] |
Common API function: handles messages from overlay to be forwarded.
method to handle decapsulated KBRdeliver messages from overlay module, should be overwritten in derived application if needed
key | destination key | |
msg | message to forward | |
nextHopNode | next hop |
Reimplemented in KBRTestApp.
void BaseApp::update | ( | const NodeHandle & | node, | |
bool | joined | |||
) | [protected, virtual] |
Common API function: informs application about neighbors and own nodeID.
node | new or lost neighbor | |
joined | new or lost? |
Reimplemented in DHT.
00279 { 00280 if(joined) { 00281 EV << "[BaseApp::update() @ " << thisNode.ip 00282 << " (" << thisNode.key.toString(16) << ")]\n" 00283 << " (" << node << ", " << joined << ") joined" 00284 << endl; 00285 } else { 00286 EV << "[BaseApp::update() @ " << thisNode.ip 00287 << " (" << thisNode.key.toString(16) << ")]\n" 00288 << " (" << node << ", " << joined << ") left" 00289 << endl; 00290 } 00291 00292 }
NodeVector* BaseApp::callLocalLookup | ( | const OverlayKey & | key, | |
int | num, | |||
bool | safe | |||
) | [inline, protected] |
Common API function: produces a list of nodes that can be used as next hops towards key.
key | the destination key | |
num | maximal number of nodes in answer | |
safe | fraction of faulty nodes is not higher than in the overlay? |
00206 { 00207 return overlay->local_lookup(key, num, safe); 00208 };
NodeVector* BaseApp::callNeighborSet | ( | int | num | ) | [inline, protected] |
Common API function: produces a list of neighbor nodes.
num | maximal number of nodes in answer |
00216 { 00217 return overlay->neighborSet(num); 00218 };
bool BaseApp::isSiblingFor | ( | const NodeHandle & | node, | |
const OverlayKey & | key, | |||
int | numSiblings, | |||
bool * | err | |||
) | [inline, protected] |
Query if a node is among the siblings for a given key.
Query if a node is among the siblings for a given key. This means, that the nodeId of this node among the close numSiblings nodes to the key and that by a local findNode() call all other siblings to this key can be retrieved.
node | the NodeHandle | |
key | destination key | |
numSiblings | The nodes knows all numSiblings nodes close to this key | |
err | return false if the range could not be determined |
00237 { 00238 return overlay->isSiblingFor(node, key, numSiblings, err); 00239 };
void BaseApp::handleTimerEvent | ( | cMessage * | msg | ) | [protected, virtual] |
processes self-messages
method to handle self-messages should be overwritten in derived application if needed
msg | self-message |
Reimplemented in DHT, GIASearchApp, KBRTestApp, RealWorldTestApp, SimpleClient, and DHTTestApp.
void BaseApp::handleAppMessage | ( | cMessage * | msg | ) | [protected, virtual] |
method to handle non-commonAPI messages from the overlay
msg | message to handle |
Reimplemented in GIASearchApp, and SimpleClient.
void BaseApp::handleUpperMessage | ( | cMessage * | msg | ) | [protected, virtual] |
handleUpperMessage gets called of handleMessage(cMessage* msg) if msg arrivedOn from_upperTier (currently msg gets deleted in this function)
msg | the message to handle |
Reimplemented in DHT, and RealWorldTestApp.
void BaseApp::sendMessageToOverlay | ( | cMessage * | msg | ) | [protected] |
sends non-commonAPI message to the overlay
msg | message to send |
00394 { 00395 RECORD_STATS(numSent++; bytesSent += msg->byteLength()); 00396 00397 send(msg, "to_lowerTier"); 00398 }
void BaseApp::sendRpcMessageToDestination | ( | int | destType, | |
const TransportAddress & | dest, | |||
const OverlayKey & | destKey, | |||
BaseOverlayMessage * | message | |||
) | [protected, virtual] |
Reimplemented from BaseRpc.
00427 { 00428 switch(destType) { 00429 case RPC_TO_UDP: 00430 callRouteDirect(dest, message); 00431 break; 00432 case RPC_TO_KEY: 00433 callRoute(destKey, message, dest); 00434 break; 00435 case RPC_TO_UPPERTIER: 00436 send(message, "to_upperTier"); 00437 break; 00438 case RPC_TO_LOWERTIER: 00439 send(message, "to_lowerTier"); 00440 break; 00441 } 00442 }
UnderlayConfigurator* BaseApp::underlayConfigurator [protected] |
BootstrapOracle* BaseApp::bootstrapOracle [protected] |
GlobalStatistics* BaseApp::globalStatistics [protected] |
NotificationBoard* BaseApp::notificationBoard [protected] |
pointer to NotificationBoard in this node
BaseOverlay* BaseApp::overlay [protected] |
BaseApp* BaseApp::tier1 [protected] |
BaseApp* BaseApp::tier2 [protected] |
BaseApp* BaseApp::tier3 [protected] |
bool BaseApp::debugOutput [protected] |
bool BaseApp::onlyCommonAPIMessages [protected] |
process/send only commonAPI messages?
int BaseApp::numSent [protected] |
int BaseApp::bytesSent [protected] |
number of sent bytes
int BaseApp::numReceived [protected] |
number of received packets
int BaseApp::bytesReceived [protected] |
number of received bytes
simtime_t BaseApp::creationTime [protected] |
simTime when the App has been created