DHTTestApp Class Reference

#include <DHTTestApp.h>

Inheritance diagram for DHTTestApp:

BaseApp BaseRpc RpcListener

List of all members.


Detailed Description

A simple test application for the DHT layer.

A simple test application that does random put and get calls on the DHT layer

Author:
Ingmar Baumgart

Public Member Functions

virtual ~DHTTestApp ()
 virtual destructor

Protected Member Functions

void initializeApp (int stage)
 initializes derived class-attributes
OverlayKey getRandomKey ()
 Get a random key of the hashmap.
char * generateRandomValue ()
 generate a random char[21]
void finishApp ()
 collects statistical data of derived app
virtual void handleGetResponse (DHTgetCAPIResponse *msg)
 processes get responses
virtual void handlePutResponse (DHTputCAPIResponse *msg)
 processes put responses
virtual void handleTimerEvent (cMessage *msg)
 processes self-messages
virtual void handleTraceMessage (cMessage *msg)
 handleTraceMessage gets called of handleMessage(cMessage* msg) if a message arrives at trace_in.
void handleRpcResponse (BaseResponseMessage *msg, int rpcId, simtime_t rtt)
 This method is called if an RPC response has been received.

Protected Attributes

UnderlayConfiguratorunderlayConfigurator
 pointer to UnderlayConfigurator in this node
BootstrapOraclebootstrapOracle
 pointer to BootstrapOracle in this node
GlobalStatisticsglobalStatistics
 pointer to GlobalStatistics module in this node
bool debugOutput
 debug output yes/no?
double mean
 mean time interval between sending test messages
double deviation
 deviation of time interval
bool activeNetwInitPhase
 is app active in network init phase?
int numSent
 number of sent packets
int numGetSent
 number of get sent
int numGetError
 number of false get responses
int numGetSuccess
 number of false get responses
int numPutSent
 number of put sent
int numPutError
 number of error in put responses
int numPutSuccess
 number of success in put responses
simtime_t lastPutTime
simtime_t lastGetTime

Constructor & Destructor Documentation

DHTTestApp::~DHTTestApp (  )  [virtual]

virtual destructor

00037 {
00038     //...
00039 }


Member Function Documentation

void DHTTestApp::initializeApp ( int  stage  )  [protected, virtual]

initializes derived class-attributes

Parameters:
stage the init stage

Reimplemented from BaseApp.

00042 {
00043     if (stage != MIN_STAGE_APP)
00044         return;
00045 
00046     // fetch parameters
00047     debugOutput = par("debugOutput");
00048     activeNetwInitPhase = par("activeNetwInitPhase");
00049 
00050     mean = par("messageDelay");
00051     deviation = mean / 10;
00052 
00053     bootstrapOracle = BootstrapOracleAccess().get();
00054     underlayConfigurator = UnderlayConfiguratorAccess().get();
00055     globalStatistics = GlobalStatisticsAccess().get();
00056 
00057     // statistics
00058     numSent = 0;
00059     numGetSent = 0;
00060     numGetError = 0;
00061     numGetSuccess = 0;
00062     numPutSent = 0;
00063     numPutError = 0;
00064     numPutSuccess = 0;
00065 
00066     initRpcs();
00067     WATCH(numSent);
00068     WATCH(numGetSent);
00069     WATCH(numGetError);
00070     WATCH(numGetSuccess);
00071     WATCH(numPutSent);
00072     WATCH(numPutError);
00073     WATCH(numPutSuccess);
00074 
00075     // initiate test message emision
00076     cMessage* dhttestput_timer = new cMessage("dhttest_put_timer");
00077     cMessage* dhttestget_timer = new cMessage("dhttest_get_timer");
00078     cMessage* dhttestmod_timer = new cMessage("dhttest_mod_timer");
00079 
00080     if (mean > 0) {
00081         scheduleAt(simulation.simTime() + truncnormal(mean, deviation),
00082                 dhttestput_timer);
00083         scheduleAt(simulation.simTime() + truncnormal(mean+mean/3, deviation),
00084                 dhttestget_timer);
00085         scheduleAt(simulation.simTime() + truncnormal(mean+2*mean/3, deviation),
00086                 dhttestmod_timer);
00087     }
00088 }

OverlayKey DHTTestApp::getRandomKey (  )  [protected]

Get a random key of the hashmap.

00273 {
00274     BootstrapOracle::DataMap* dataMap = bootstrapOracle->getDataMap();
00275 
00276     if (dataMap->size() == 0)
00277         return OverlayKey::UNSPECIFIED_KEY;
00278 
00279     // return random OverlayKey in O(log n) (taken from BootstrapOracle)
00280     std::map<OverlayKey, DHTEntry>::iterator it = dataMap->end();
00281     DHTEntry tempEntry = { NULL, 0 };
00282 
00283     while (it == dataMap->end()) {
00284         OverlayKey randomKey = OverlayKey::random();
00285 
00286         it = dataMap->find(randomKey);
00287 
00288         if (it == dataMap->end()) {
00289             it = dataMap->insert(std::make_pair(randomKey,tempEntry)).first;
00290             dataMap->erase(it++);
00291         }
00292 
00293         if (it == dataMap->end())
00294             it = dataMap->begin();
00295     }
00296     return it->first;
00297 }

char * DHTTestApp::generateRandomValue (  )  [protected]

generate a random char[21]

00300 {
00301     char* value;
00302     value = (char *)malloc(sizeof(char)*21);
00303     int i, randvalue;
00304 
00305     for (i=0; i < 20; i++) {
00306         randvalue = (int)intuniform(0, 25);
00307         value[i] = randvalue+'a';
00308     }
00309 
00310     value[20] = '\0';
00311     return value;
00312 }

void DHTTestApp::finishApp (  )  [protected, virtual]

collects statistical data of derived app

Reimplemented from BaseApp.

00315 {
00316     // record scalar data
00317     globalStatistics->addStdDev("DHTTest: Sent Messages", numSent);
00318     globalStatistics->addStdDev("DHTTest: Get Messages sent", numGetSent);
00319     globalStatistics->addStdDev("DHTTest: Get Errors", numGetError);
00320     globalStatistics->addStdDev("DHTTest: Get Success", numGetSuccess);
00321     if (numGetSent > 0) {
00322         globalStatistics->addStdDev("DHTTest: Get Success Ratio",
00323                                         (double)numGetSuccess/(double)numGetSent);
00324     } else { 
00325         globalStatistics->addStdDev("DHTTest: Get Success Ratio", 0);
00326     }
00327     globalStatistics->addStdDev("DHTTest: Put Messages sent", numPutSent);
00328     globalStatistics->addStdDev("DHTTest: Put Errors", numPutError);
00329     globalStatistics->addStdDev("DHTTest: Put Success", numPutSuccess);
00330 }

void DHTTestApp::handleGetResponse ( DHTgetCAPIResponse *  msg  )  [protected, virtual]

processes get responses

method to handle get responses should be overwritten in derived application if needed

Parameters:
msg get response message
00127 {
00128     OverlayKey key = msg->getKey();
00129     globalStatistics->addStdDev("DHTTest: Get length (s)",
00130                                 simTime() - lastGetTime);
00131 
00132     if (!(msg->getIsSuccess())) {
00133         numGetError++;
00134         return;
00135     }
00136     std::map<OverlayKey, DHTEntry>::iterator it = bootstrapOracle->getDataMap()->find(key);
00137 
00138     if (it == bootstrapOracle->getDataMap()->end()) {
00139         //unexpected key
00140         numGetError++;
00141         return;
00142     }
00143 
00144     DHTEntry entry = it->second;
00145     if (simulation.simTime() > entry.endtime) {
00146         //this key doesn't exist anymore in the DHT, delete it in our hashtable
00147         bootstrapOracle->getDataMap()->erase(key);
00148         if (msg->getValue() != BinaryValue::UNSPECIFIED_VALUE) {
00149             numGetError++;
00150             return;
00151         } else {
00152             numGetSuccess++;
00153             return;
00154         }
00155     } else {
00156         if (dynamic_cast< vector<char>& >((msg->getValue()))
00157                 != dynamic_cast< vector<char>& >(*(entry.value))) {
00158             numGetError++;
00159             return;
00160         } else {
00161             numGetSuccess++;
00162             return;
00163         }
00164     }
00165 
00166 }

void DHTTestApp::handlePutResponse ( DHTputCAPIResponse *  msg  )  [protected, virtual]

processes put responses

method to handle put responses should be overwritten in derived application if needed

Parameters:
msg put response message
00110 {
00111     OverlayKey key = msg->getKey();
00112     globalStatistics->addStdDev("DHTTest: Put length (s)", simTime()
00113             - lastPutTime);
00114     if (!(msg->getIsSuccess())) {
00115         numPutError++;
00116         return;
00117     }
00118     numPutSuccess++;
00119     DHTEntry entry;
00120     entry.value = new BinaryValue(msg->getValue());
00121     entry.endtime = simulation.simTime()+DEFAULT_TTL;
00122     bootstrapOracle->getDataMap()->erase(msg->getKey());
00123     bootstrapOracle->getDataMap()->insert(make_pair(msg->getKey(), entry));
00124 }

void DHTTestApp::handleTimerEvent ( cMessage *  msg  )  [protected, virtual]

processes self-messages

method to handle self-messages should be overwritten in derived application if needed

Parameters:
msg self-message

Reimplemented from BaseApp.

00215 {
00216     if (msg->isName("dhttest_put_timer")) {
00217         // schedule next timer event
00218         scheduleAt(simulation.simTime() + truncnormal(mean, deviation), msg);
00219 
00220         // do nothing if the network is still in the initialization phase
00221         if ((!activeNetwInitPhase) && (underlayConfigurator->isInit()))
00222             return;
00223 
00224         // create a put test message with random destination key
00225         OverlayKey destKey = OverlayKey::random();
00226         DHTputCAPICall* dhtPutMsg = new DHTputCAPICall();
00227         char * value = generateRandomValue();
00228         dhtPutMsg->setKey(destKey);
00229         dhtPutMsg->setValue(value);
00230         dhtPutMsg->setTtl(DEFAULT_TTL);
00231         dhtPutMsg->setIsModifiable(true);
00232         free(value);
00233 
00234         lastPutTime = simTime();
00235         numSent++;
00236         numPutSent++;
00237         sendInternalRpcCall(TIER1_COMP, dhtPutMsg);
00238     } else  if (msg->isName("dhttest_get_timer")) {
00239         scheduleAt(simulation.simTime() + truncnormal(mean, deviation), msg);
00240         OverlayKey key = getRandomKey();
00241         
00242         if (key.isUnspecified())
00243             return;
00244         
00245         DHTgetCAPICall* dhtGetMsg = new DHTgetCAPICall();
00246         dhtGetMsg->setKey(key);
00247         lastGetTime = simTime();
00248         numSent++;
00249         numGetSent++;
00250         sendInternalRpcCall(TIER1_COMP, dhtGetMsg);
00251     } else if (msg->isName("dhttest_mod_timer")) {
00252         scheduleAt(simulation.simTime() + truncnormal(mean, deviation), msg);
00253         OverlayKey key = getRandomKey();
00254 
00255         if (key.isUnspecified())
00256             return;
00257 
00258         DHTputCAPICall* dhtPutMsg = new DHTputCAPICall();
00259         char * value = generateRandomValue();
00260         dhtPutMsg->setKey(key);
00261         dhtPutMsg->setValue(value);
00262         dhtPutMsg->setTtl(DEFAULT_TTL);
00263         dhtPutMsg->setIsModifiable(true);
00264         free(value);
00265         lastPutTime = simTime();
00266         numSent++;
00267         numPutSent++;
00268         sendInternalRpcCall(TIER1_COMP, dhtPutMsg);
00269     }
00270 }

void DHTTestApp::handleTraceMessage ( cMessage *  msg  )  [protected, virtual]

handleTraceMessage gets called of handleMessage(cMessage* msg) if a message arrives at trace_in.

The command included in this message should be parsed and handled.

Parameters:
msg the command message to handle

Reimplemented from BaseApp.

00169 {
00170     char* cmd = new char[strlen(msg->name())];
00171     strcpy(cmd, msg->name());
00172     if (strncmp(cmd, "PUT ", 4) == 0) {
00173         // Generate key
00174         char* buf = cmd + 4;
00175         while (!isspace(buf[0])) {
00176             if ( buf[0] == '\0' ) throw new cException("Error parsing PUT command");
00177             buf++;
00178         }
00179         buf[0] = '\0';
00180         BinaryValue b(cmd+4);
00181         OverlayKey destKey(OverlayKey::sha1(b));
00182 
00183         // get value
00184         buf++;
00185 
00186         // build putMsg
00187         DHTputCAPICall* dhtPutMsg = new DHTputCAPICall();
00188         dhtPutMsg->setKey(destKey);
00189         dhtPutMsg->setValue(buf);
00190         dhtPutMsg->setTtl(DEFAULT_TTL);
00191         dhtPutMsg->setIsModifiable(true);
00192 
00193         numSent++;
00194         numPutSent++;
00195         sendInternalRpcCall(TIER1_COMP, dhtPutMsg);
00196         delete cmd;
00197     } else if (strncmp(cmd, "GET ", 4) == 0) {
00198         // Get key
00199         BinaryValue b(cmd+4);
00200         OverlayKey key(OverlayKey::sha1(b));
00201 
00202         DHTgetCAPICall* dhtGetMsg = new DHTgetCAPICall();
00203         dhtGetMsg->setKey(key);
00204         lastGetTime = simTime();
00205         numSent++;
00206         numGetSent++;
00207         sendInternalRpcCall(TIER1_COMP, dhtGetMsg);
00208     } else {
00209         throw new cRuntimeError("Unknown trace command; "
00210                                 "only GET and PUT are allowed");
00211     }
00212 }

void DHTTestApp::handleRpcResponse ( BaseResponseMessage *  msg,
int  rpcId,
simtime_t  rtt 
) [protected, virtual]

This method is called if an RPC response has been received.

Parameters:
msg The response message.
rpcId The RPC id.
rtt The Round-Trip-Time of this RPC

Reimplemented from RpcListener.

00092 {
00093     RPC_SWITCH_START(msg)
00094     RPC_ON_RESPONSE( DHTputCAPI ) {
00095         handlePutResponse(_DHTputCAPIResponse);
00096         EV << "DHT Put RPC Response received: id=" << rpcId
00097            << " msg=" << *_DHTputCAPIResponse << " rtt=" << rtt << endl;
00098         break;
00099     }
00100     RPC_ON_RESPONSE( DHTgetCAPI ) {
00101         handleGetResponse(_DHTgetCAPIResponse);
00102         EV << "DHT Get RPC Response received: id=" << rpcId
00103            << " msg=" << *_DHTgetCAPIResponse << " rtt=" << rtt << endl;
00104         break;
00105     }
00106     RPC_SWITCH_END( )
00107 }


Member Data Documentation

UnderlayConfigurator* DHTTestApp::underlayConfigurator [protected]

pointer to UnderlayConfigurator in this node

Reimplemented from BaseApp.

BootstrapOracle* DHTTestApp::bootstrapOracle [protected]

pointer to BootstrapOracle in this node

Reimplemented from BaseApp.

GlobalStatistics* DHTTestApp::globalStatistics [protected]

pointer to GlobalStatistics module in this node

Reimplemented from BaseApp.

bool DHTTestApp::debugOutput [protected]

debug output yes/no?

Reimplemented from BaseApp.

double DHTTestApp::mean [protected]

mean time interval between sending test messages

double DHTTestApp::deviation [protected]

deviation of time interval

bool DHTTestApp::activeNetwInitPhase [protected]

is app active in network init phase?

int DHTTestApp::numSent [protected]

number of sent packets

Reimplemented from BaseApp.

int DHTTestApp::numGetSent [protected]

number of get sent

int DHTTestApp::numGetError [protected]

number of false get responses

int DHTTestApp::numGetSuccess [protected]

number of false get responses

int DHTTestApp::numPutSent [protected]

number of put sent

int DHTTestApp::numPutError [protected]

number of error in put responses

int DHTTestApp::numPutSuccess [protected]

number of success in put responses

simtime_t DHTTestApp::lastPutTime [protected]

simtime_t DHTTestApp::lastGetTime [protected]


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:28 2008 for ITM OverSim by  doxygen 1.5.3