00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "cgicc/CgiDefs.h"
00013 #include "cgicc/Cgicc.h"
00014 #include "cgicc/HTTPHTMLHeader.h"
00015 #include "cgicc/HTMLClasses.h"
00016 #include "cgicc/HTTPResponseHeader.h"
00017
00018
00019 #include "xdaq/ApplicationGroup.h"
00020 #include "xdaq/ApplicationRegistry.h"
00021
00022 #include "xoap/MessageReference.h"
00023 #include "xoap/MessageFactory.h"
00024 #include "xoap/SOAPEnvelope.h"
00025 #include "xoap/SOAPPart.h"
00026 #include "xoap/SOAPBody.h"
00027 #include "xoap/SOAPBodyElement.h"
00028 #include "xoap/Method.h"
00029 #include "xoap/domutils.h"
00030 #include "xoap/DOMParser.h"
00031 #include "xoap/SOAPHeader.h"
00032
00033 #include "xgi/Table.h"
00034 #include "xcept/tools.h"
00035
00036 #include "DQMServices/XdaqCollector/interface/XmasToDQM.h"
00037
00038 #include "toolbox/task/WorkLoopFactory.h"
00039 #include "xdata/InfoSpaceFactory.h"
00040
00041
00042
00043
00044 #include "toolbox/Runtime.h"
00045
00046
00047 #include "xdata/exdr/FixedSizeInputStreamBuffer.h"
00048 #include "xdata/Table.h"
00049 #include "xdata/exdr/Serializer.h"
00050 #include "xdata/exdr/AutoSizeOutputStreamBuffer.h"
00051 #include "xdaq/ApplicationDescriptorImpl.h"
00052
00053 #include "toolbox/TimeVal.h"
00054 #include "toolbox/stl.h"
00055 #include "toolbox/regex.h"
00056
00057
00058
00059
00060
00061
00062
00063 #include "xoap/Event.h"
00064
00065 #include<boost/tokenizer.hpp>
00066
00067
00068
00069 XDAQ_INSTANTIATOR_IMPL(xmas2dqm::wse::XmasToDQM)
00070
00071 xmas2dqm::wse::XmasToDQM::XmasToDQM(xdaq::ApplicationStub* s) throw (xdaq::exception::Exception)
00072 : xdaq::Application(s)
00073 {
00074 getApplicationDescriptor()->setAttribute("icon", "/xmas2dqm/wse/images/Las.png");
00075
00076 LOG4CPLUS_DEBUG(this->getApplicationLogger(),"inside constructor of xmas2dqm::wse::Application");
00077
00078
00079
00080
00081
00082
00083
00084
00085 xoap::bind(this, &xmas2dqm::wse::XmasToDQM::fireEvent, "Enable", XDAQ_NS_URI );
00086 xoap::bind(this, &xmas2dqm::wse::XmasToDQM::fireEvent, "Halt", XDAQ_NS_URI );
00087 xoap::bind(this, &xmas2dqm::wse::XmasToDQM::reset, "Reset", XDAQ_NS_URI );
00088
00089
00090
00091
00092 fsm_.addState('H', "Halted", this, &xmas2dqm::wse::XmasToDQM::stateChanged);
00093 fsm_.addState('E', "Enabled", this, &xmas2dqm::wse::XmasToDQM::stateChanged);
00094
00095 fsm_.addStateTransition('H', 'E', "Enable", this,&xmas2dqm::wse::XmasToDQM::EnableAction);
00096 fsm_.addStateTransition('H', 'H', "Halt", this, &xmas2dqm::wse::XmasToDQM::HaltAction);
00097 fsm_.addStateTransition('E', 'H', "Halt", this, &xmas2dqm::wse::XmasToDQM::HaltAction);
00098
00099
00100 fsm_.setFailedStateTransitionAction( this, &xmas2dqm::wse::XmasToDQM::failedTransition );
00101 fsm_.setFailedStateTransitionChanged(this, &xmas2dqm::wse::XmasToDQM::stateChanged );
00102
00103 fsm_.setInitialState('H');
00104 fsm_.setStateName('F', "Failed");
00105
00106 fsm_.reset();
00107
00108
00109 state_ = fsm_.getStateName (fsm_.getCurrentState());
00110 getApplicationInfoSpace()->fireItemAvailable("stateName",&state_);
00111 getApplicationInfoSpace()->fireItemAvailable("LASurl",&LASurl_);
00112 getApplicationInfoSpace()->fireItemAvailable("Period",&Period_);
00113 getApplicationInfoSpace()->fireItemAvailable("LASQueueSize",&LASQueueSize_);
00114 getApplicationInfoSpace()->fireItemAvailable("flashlistMonitor",&xmas2dqm::wse::ToDqm::instance()->flashlistMonitor_);
00115 getApplicationInfoSpace()->fireItemAvailable("runNumber",&xmas2dqm::wse::ToDqm::instance()->runNumber_);
00116
00117
00118 getApplicationInfoSpace()->addItemChangedListener ("stateName", this);
00119 getApplicationInfoSpace()->addItemChangedListener ("LASurl", this);
00120 getApplicationInfoSpace()->addItemChangedListener ("Period", this);
00121 getApplicationInfoSpace()->addItemChangedListener ("LASQueueSize", this);
00122 getApplicationInfoSpace()->addItemChangedListener ("flashlistMonitor", this);
00123 getApplicationInfoSpace()->addItemChangedListener ("runNumber", this);
00124
00125 LASurl_ = "https://srv-c2d04-18.cms:9943/urn:xdaq-application:lid=100/retrieveCollection";
00126 Period_ = "10";
00127 LASQueueSize_ = "100000";
00128
00129
00130
00131
00132
00133
00134 curl_global_init(CURL_GLOBAL_ALL);
00135
00136 LASReadout_ = toolbox::task::bind (this, &xmas2dqm::wse::XmasToDQM::LASReadoutWorkLoop, "LASReadoutWorkLoop");
00137
00138 LASReadoutWorkLoop_ = toolbox::task::getWorkLoopFactory()->getWorkLoop("LASReadoutWaitingWorkLoop", "waiting");
00139
00140
00141 if (LASReadoutWorkLoop_->isActive() == false)
00142 {
00143 LASReadoutWorkLoop_->activate();
00144
00145 }
00146
00147
00148
00149 LASReadoutTimer_ = toolbox::task::getTimerFactory()->createTimer("PeriodicLASReadout");
00150
00151
00152
00153
00154
00155
00156
00157 LOG4CPLUS_DEBUG(this->getApplicationLogger(),"finish of Constructor of xmas2dqm::wse::XmasToDQM");
00158
00159 }
00160
00161
00162 bool xmas2dqm::wse::XmasToDQM::LASReadoutWorkLoop (toolbox::task::WorkLoop* wl)
00163 {
00164
00165 static int times = 0;
00166 times++;
00167
00168 LOG4CPLUS_DEBUG (getApplicationLogger(), "inside WorkLoop...ready to ask LAS for EXDR data : time " << times <<"th");
00169 LOG4CPLUS_DEBUG (getApplicationLogger(), "Period = " + Period_.toString() + " LASurl = " + LASurl_.toString());
00170
00171
00172 xdata::Table * ptr_table = new xdata::Table();
00173
00174 int ret = getEXDR_LAS(ptr_table);
00175
00176 LOG4CPLUS_DEBUG (getApplicationLogger(), "return value from getEXDR_LAS = " << ret );
00177
00178 if (ret == -1 || ret == -2)
00179 {
00180
00181
00182
00183
00184
00185 LOG4CPLUS_DEBUG (getApplicationLogger(), "LASWorkLoop freeing xdata::Table * space" );
00186
00187 delete ptr_table;
00188
00189 LOG4CPLUS_WARN (getApplicationLogger(), "getEXDRLAS didn't complete properly, returning from LASREeadoutWorkLoop" );
00190 return false;
00191 }
00192
00193
00194
00195 LOG4CPLUS_DEBUG (getApplicationLogger(), "inside WorkLoop...lock the mutex ");
00196
00197
00198
00199
00200 pthread_mutex_lock(&xmas2dqm::wse::ToDqm::instance()->LASmutex_);
00201
00202 LOG4CPLUS_INFO (getApplicationLogger(), "inside WorkLoop...check (...and possible wait) if data queue is full");
00203
00204
00205
00206 while (xmas2dqm::wse::ToDqm::instance()->MemoryTable_.size() >= (unsigned int) atoi(LASQueueSize_.toString().c_str()))
00207 {
00208 pthread_cond_wait(&xmas2dqm::wse::ToDqm::instance()->less_, &xmas2dqm::wse::ToDqm::instance()->LASmutex_);
00209 }
00210
00211 LOG4CPLUS_DEBUG (getApplicationLogger(), "data queue has available store...proceeding...");
00212
00213
00214
00215 std::map<std::string, std::string, std::less<std::string> >::iterator i;
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 LOG4CPLUS_DEBUG (getApplicationLogger(), "inside WorkLoop...ready to call XmastoDQM::ToDQM::digest " );
00236
00237
00238 xmas2dqm::wse::ToDqm::instance()->digest("flashListName", "originator", "tagName", ptr_table );
00239
00240 LOG4CPLUS_DEBUG (getApplicationLogger(), "inside WorkLoop...signaling new element added to the data queue ");
00241
00242
00243 pthread_cond_signal(&xmas2dqm::wse::ToDqm::instance()->more_);
00244
00245 LOG4CPLUS_DEBUG (getApplicationLogger(), "inside WorkLoop...release mutex, allow access to the data queue");
00246
00247
00248 pthread_mutex_unlock(&xmas2dqm::wse::ToDqm::instance()->LASmutex_);
00249
00250 return false;
00251 }
00252
00253
00254
00255 int xmas2dqm::wse::XmasToDQM::getEXDR_LAS( xdata::Table * rtable)
00256 {
00257 LOG4CPLUS_DEBUG(this->getApplicationLogger(),"inside getEXDR_LAS.........");
00258
00259 CURL *curl_handle;
00260 CURLcode code;
00261
00262 char data[200] = "fmt=exdr&flash=";
00263
00264 strcat(data, xmas2dqm::wse::ToDqm::instance()->flashlistMonitor_.bag.flashlist.toString().c_str());
00265
00266
00267 struct MemoryStruct chunk;
00268
00269 chunk.memory=NULL;
00270 chunk.size = 0;
00271
00272
00273 curl_handle = curl_easy_init();
00274
00275 if (curl_handle == NULL)
00276 {
00277 LOG4CPLUS_WARN(getApplicationLogger(), "Failed to create CURL connection");
00278
00279 return -2;
00280 }
00281
00282 code = curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);
00283 if (code != CURLE_OK)
00284 {
00285 LOG4CPLUS_WARN (getApplicationLogger(),"Failed to set post fields");
00286
00287 return -2;
00288 }
00289
00290
00291 curl_easy_setopt(curl_handle, CURLOPT_URL, LASurl_.toString().c_str());
00292
00293
00294 curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
00295
00296
00297
00298
00299 curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
00300
00301
00302
00303 curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
00304
00305
00306 curl_easy_perform(curl_handle);
00307
00308
00309 curl_easy_cleanup(curl_handle);
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 LOG4CPLUS_DEBUG (getApplicationLogger(),"chunk.memory length = " << chunk.size);
00321
00322 xdata::exdr::FixedSizeInputStreamBuffer inBuffer(chunk.memory,chunk.size);
00323
00324
00325
00326
00327 xdata::exdr::Serializer serializer;
00328
00329 try
00330 {
00331 serializer.import( rtable, &inBuffer );
00332
00333 }
00334 catch(xdata::exception::Exception & e )
00335 {
00336 LOG4CPLUS_ERROR(this->getApplicationLogger(),"xdata::exdr::Serializer exception occured...");
00337 LOG4CPLUS_ERROR(this->getApplicationLogger(),xcept::stdformat_exception_history(e));
00338
00339 if(chunk.size > 0)
00340 free(chunk.memory);
00341
00342 return -1 ;
00343 }
00344
00345 if(chunk.size > 0)
00346 free(chunk.memory);
00347
00348 return 0;
00349 }
00350
00351
00352
00353
00356 void xmas2dqm::wse::XmasToDQM::timeExpired (toolbox::task::TimerEvent& e)
00357 {
00358
00359 static int times = 0;
00360
00361 times++;
00362
00363 LOG4CPLUS_DEBUG (getApplicationLogger(), "timeExpired was called... : time " << times <<"th");
00364 LASReadoutWorkLoop_->submit(LASReadout_);
00365
00366 }
00367
00368
00369 void *xmas2dqm::wse::XmasToDQM::myrealloc(void *ptr, size_t size)
00370 {
00371
00372
00373 if(ptr)
00374 return realloc(ptr, size);
00375 else
00376 return malloc(size);
00377 }
00378
00379
00380
00381 size_t xmas2dqm::wse::XmasToDQM::WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
00382 {
00383 size_t realsize = size * nmemb;
00384 struct MemoryStruct *mem = (struct MemoryStruct *)data;
00385
00386 mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
00387 if (mem->memory)
00388 {
00389 memcpy(&(mem->memory[mem->size]), ptr, realsize);
00390 mem->size += realsize;
00391 mem->memory[mem->size] = 0;
00392 }
00393 return realsize;
00394 }
00395
00396
00397
00398
00399 void xmas2dqm::wse::XmasToDQM::actionPerformed (xdata::Event& e)
00400 {
00401 LOG4CPLUS_DEBUG(getApplicationLogger(), "start of actionperformed");
00402 LOG4CPLUS_DEBUG(getApplicationLogger(), e.type());
00403
00404
00405 if (e.type() == "ItemChangedEvent")
00406 {
00407 std::string item = dynamic_cast<xdata::ItemChangedEvent&>(e).itemName();
00408
00409 if ( item == "Period")
00410 {
00411
00412 LOG4CPLUS_DEBUG(getApplicationLogger(), "item = " + item);
00413
00414 if(fsm_.getStateName (fsm_.getCurrentState()) != "Enabled")
00415 {
00416 return;
00417 }
00418
00419 try
00420 {
00421 LASReadoutTimer_->remove(std::string("LASReadout"));
00422 }
00423 catch(toolbox::task::exception::NotActive &e)
00424 {
00425 LOG4CPLUS_WARN(getApplicationLogger(), "toolbox::task::exception::NotActive exception occured...");
00426 }
00427 catch(toolbox::task::exception::NoJobs)
00428 {
00429 LOG4CPLUS_WARN(getApplicationLogger(), "toolbox::task::exception::NoJobs exception occured...");
00430 }
00431 catch(toolbox::task::exception::JobNotFound &e)
00432 {
00433 LOG4CPLUS_WARN(getApplicationLogger(), "toolbox::task::exception::JobNotFound exception occured...");
00434 toolbox::TimeInterval interval(atoi(Period_.toString().c_str()),0);
00435
00436 }
00437
00438
00439
00440 toolbox::TimeInterval interval(atoi(Period_.toString().c_str()),0);
00441
00442 startLASReadout_ = toolbox::TimeVal::gettimeofday();
00443
00444 LASReadoutTimer_->scheduleAtFixedRate( startLASReadout_, this, interval, 0, std::string("LASReadout") );
00445 }
00446
00447
00448 if ( item == "flashlistMonitor")
00449 {
00450
00451 LOG4CPLUS_INFO(getApplicationLogger(), "flashlist = " << xmas2dqm::wse::ToDqm::instance()->flashlistMonitor_.bag.flashlist.toString());
00452 LOG4CPLUS_INFO(getApplicationLogger(), "element = " << xmas2dqm::wse::ToDqm::instance()->flashlistMonitor_.bag.element.toString());
00453 LOG4CPLUS_INFO(getApplicationLogger(), "xtitle = " << xmas2dqm::wse::ToDqm::instance()->flashlistMonitor_.bag.xtitle.toString());
00454 LOG4CPLUS_INFO(getApplicationLogger(), "ytitle = " << xmas2dqm::wse::ToDqm::instance()->flashlistMonitor_.bag.ytitle.toString());
00455
00456
00457
00458 }
00459
00460 if ( item == "runNumber")
00461 {
00462
00463 LOG4CPLUS_INFO(getApplicationLogger(), "set runNumber to... = " << xmas2dqm::wse::ToDqm::instance()->runNumber_.toString());
00464 }
00465
00466 }
00467
00468 LOG4CPLUS_DEBUG(getApplicationLogger(), "end of actionperformed");
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 xmas2dqm::wse::XmasToDQM::~XmasToDQM()
00485 {
00486
00487 }
00488
00489
00490 xoap::MessageReference xmas2dqm::wse::XmasToDQM::fireEvent (xoap::MessageReference msg)
00491 throw (xoap::exception::Exception)
00492 {
00493 xoap::SOAPPart part = msg->getSOAPPart();
00494 xoap::SOAPEnvelope env = part.getEnvelope();
00495 xoap::SOAPBody body = env.getBody();
00496 DOMNode* node = body.getDOMNode();
00497 DOMNodeList* bodyList = node->getChildNodes();
00498 for (unsigned int i = 0; i < bodyList->getLength(); i++)
00499 {
00500 DOMNode* command = bodyList->item(i);
00501
00502 if (command->getNodeType() == DOMNode::ELEMENT_NODE)
00503 {
00504
00505 std::string commandName = xoap::XMLCh2String (command->getLocalName());
00506
00507
00508 try
00509 {
00510 toolbox::Event::Reference e(new toolbox::Event(commandName,this));
00511 fsm_.fireEvent(e);
00512 }
00513 catch (toolbox::fsm::exception::Exception & e)
00514 {
00515 XCEPT_RETHROW(xoap::exception::Exception, "invalid command", e);
00516 }
00517
00518 xoap::MessageReference reply = xoap::createMessage();
00519 xoap::SOAPEnvelope envelope = reply->getSOAPPart().getEnvelope();
00520 xoap::SOAPName responseName = envelope.createName( commandName +"Response", "xdaq", XDAQ_NS_URI);
00521
00522 (void) envelope.getBody().addBodyElement ( responseName );
00523 return reply;
00524 }
00525 }
00526
00527 XCEPT_RAISE(xcept::Exception,"command not found");
00528 }
00529
00530
00531 xoap::MessageReference xmas2dqm::wse::XmasToDQM::reset (xoap::MessageReference msg) throw (xoap::exception::Exception)
00532 {
00533 LOG4CPLUS_DEBUG (getApplicationLogger(), "New state before reset is: " << fsm_.getStateName (fsm_.getCurrentState()) );
00534
00535 fsm_.reset();
00536 state_ = fsm_.getStateName (fsm_.getCurrentState());
00537
00538 xoap::MessageReference reply = xoap::createMessage();
00539 xoap::SOAPEnvelope envelope = reply->getSOAPPart().getEnvelope();
00540 xoap::SOAPName responseName = envelope.createName("ResetResponse", "xdaq", XDAQ_NS_URI);
00541
00542 (void) envelope.getBody().addBodyElement ( responseName );
00543
00544 LOG4CPLUS_DEBUG (getApplicationLogger(), "New state after reset is: " << fsm_.getStateName (fsm_.getCurrentState()) );
00545
00546 return reply;
00547 }
00548
00549
00550 void xmas2dqm::wse::XmasToDQM::EnableAction (toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00551 {
00552 LOG4CPLUS_DEBUG (getApplicationLogger(), e->type());
00553
00554
00555 try
00556 {
00557 LASReadoutTimer_->remove(std::string("LASReadout"));
00558 }
00559 catch(toolbox::task::exception::NotActive &e)
00560 {
00561 LOG4CPLUS_WARN(getApplicationLogger(), "toolbox::task::exception::NotActive exception occured...");
00562 }
00563 catch(toolbox::task::exception::NoJobs)
00564 {
00565 LOG4CPLUS_INFO(getApplicationLogger(), "toolbox::task::exception::NoJobs exception occured...");
00566 }
00567 catch(toolbox::task::exception::JobNotFound &e)
00568 {
00569 LOG4CPLUS_INFO(getApplicationLogger(), "toolbox::task::exception::JobNotFound exception occured...");
00570 toolbox::TimeInterval interval(atoi(Period_.toString().c_str()),0);
00571
00572 }
00573
00574
00575 toolbox::TimeInterval interval(atoi(Period_.toString().c_str()),0);
00576
00577 startLASReadout_ = toolbox::TimeVal::gettimeofday();
00578
00579 LASReadoutTimer_->scheduleAtFixedRate( startLASReadout_, this, interval, 0, std::string("LASReadout") );
00580
00581 }
00582
00583
00584 void xmas2dqm::wse::XmasToDQM::HaltAction (toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00585 {
00586 LOG4CPLUS_DEBUG (getApplicationLogger(), e->type());
00587
00588 try
00589 {
00590 LASReadoutTimer_->remove(std::string("LASReadout"));
00591 }
00592 catch(toolbox::task::exception::NotActive &e)
00593 {
00594 LOG4CPLUS_WARN(getApplicationLogger(), "toolbox::task::exception::NotActive exception occured...");
00595 }
00596 catch(toolbox::task::exception::NoJobs)
00597 {
00598 LOG4CPLUS_WARN(getApplicationLogger(), "toolbox::task::exception::NoJobs exception occured...");
00599 }
00600 catch(toolbox::task::exception::JobNotFound &e)
00601 {
00602 LOG4CPLUS_WARN(getApplicationLogger(), "toolbox::task::exception::JobNotFound exception occured...");
00603 toolbox::TimeInterval interval(atoi(Period_.toString().c_str()),0);
00604
00605 }
00606
00607 }
00608
00609
00610
00611 void xmas2dqm::wse::XmasToDQM::stateChanged (toolbox::fsm::FiniteStateMachine & fsm) throw (toolbox::fsm::exception::Exception)
00612 {
00613
00614 state_ = fsm.getStateName (fsm.getCurrentState());
00615 LOG4CPLUS_DEBUG (getApplicationLogger(), "New state is:" << fsm.getStateName (fsm.getCurrentState()) );
00616 }
00617
00618 void xmas2dqm::wse::XmasToDQM::failedTransition (toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00619 {
00620 toolbox::fsm::FailedEvent & fe = dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
00621 LOG4CPLUS_ERROR (getApplicationLogger(), "Failure occurred when performing transition from: " <<
00622 fe.getFromState() << " to: " << fe.getToState() << " exception: " << fe.getException().what() );
00623 }
00624
00625