Service.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright 2007, 2008, 2009, 2010, 2011 Instituto de Sistemas e Robotica, Instituto Superior Tecnico
00003 
00004 This file is part of MeRMaID.
00005 
00006 MeRMaID is free software: you can redistribute it and/or modify
00007 it under the terms of the GNU Lesser General Public License as published by
00008 the Free Software Foundation, either version 3 of the License, or
00009 (at your option) any later version.
00010 
00011 MeRMaID is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public License
00017 along with MeRMaID.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 
00021 
00022 /**
00023  * @Filename Service.cpp
00024  * @Description Support Service implementation
00025  * @Status Work in Progress
00026  * @Version $Id: Service.cpp 1 2011-03-04 18:13:18Z jreis $
00027  * @Maintainer Marco Barbosa
00028  */
00029 
00030 
00031 #include "config.h"
00032 
00033 #include "Service.hpp"
00034 #include "DataFeed.hpp"
00035 #include "DataFeedDescription.hpp"
00036 #include "Entity.hpp"
00037 #include "EntityDescription.hpp"
00038 #include "ServiceInterface.hpp"
00039 #include "ServiceInterfaceDescription.hpp"
00040 #include "ServiceTypeDescriptionFactory.hpp"
00041 #include "ServiceUpdateTask.hpp"
00042 #include "Exceptions/ServiceRequestFailedException.hpp"
00043 
00044 #include <CommunicationGateway.hpp>
00045 #include <DataValueVector.hpp>
00046 #include <Exception.hpp>
00047 #include <DataFactory.hpp>
00048 #include <YarpDataFeedSetupTask.hpp>
00049 
00050 #include <sstream>
00051 
00052 using namespace mermaid::support::service;
00053 
00054 using mermaid::support::communication::CommunicationGateway;
00055 using mermaid::support::data::DataFactory;
00056 using mermaid::support::data::DataValueVector;
00057 using mermaid::support::data::String;
00058 using mermaid::support::errorhandling::Exception;
00059 
00060 using mermaid::support::logging::FastLogger;
00061 
00062 #ifdef USE_COMM
00063 using mermaid::support::communication::YarpDataFeedSetupTask;
00064 #endif
00065 
00066 #include <iostream>
00067 
00068 shared_ptr<ServiceTypeDescriptionRepository> Service::serviceTypeDescriptionRepository_ = shared_ptr<ServiceTypeDescriptionRepository>();
00069 
00070 Service::Service (shared_ptr<ActiveObject> ao, shared_ptr<Entity> entity, shared_ptr<ServiceInstanceDescription> serviceInstanceDescription, shared_ptr<ServiceConfiguration> serviceConfiguration)
00071 {
00072   activeObject_ = ao;
00073   entity_ = entity;
00074   serviceInstanceDescription_ = serviceInstanceDescription;
00075   serviceConfiguration_ = serviceConfiguration;
00076   
00077   float updateFreq = serviceConfiguration->getServiceUpdateFrequency();
00078   if (updateFreq != 0.0) {
00079     shared_ptr<Task> serviceUpdateTask (new ServiceUpdateTask (this));
00080     activeObject_->addTask (serviceUpdateTask);
00081   }
00082   
00083   lastRequestId_ = 0;
00084   
00085   logger_ = FastLogger::build (serviceInstanceDescription_->getServiceInstanceName());
00086   debugLogger_ = FastLogger::build (serviceInstanceDescription_->getServiceInstanceName() + " DEBUG");
00087 }; // Service()
00088 
00089 
00090 Service::~Service()
00091 {
00092 //  std::cerr << "Service::~Service()" << std::endl;
00093 };
00094 
00095 
00096 void Service::update()
00097 {
00098   //std::cerr << "Service::update()" << std::endl;
00099 }; // update()
00100 
00101 void Service::processServiceRequest (shared_ptr<ServiceRequest> request)
00102 {
00103   std::string requesterEntityName = request->getRequesterEntityName();
00104   std::string requesterServiceName = request->getRequesterServiceName();
00105   std::string targetEntityName = request->getTargetEntityName();
00106   std::string targetServiceName = request->getTargetServiceName();
00107   std::string targetServiceInterfaceName = request->getTargetServiceInterfaceName();
00108   //int requestId = request->getRequestId();
00109   shared_ptr<Service> targetService = entity_->getService (serviceInstanceDescription_->getServiceInstanceName());
00110   
00111   /*std::cerr << "Service::processServiceRequest" << std::endl;
00112   std::cerr << "\trequesterEntityName:\t" << requesterEntityName << std::endl;
00113   std::cerr << "\trequesterServiceName:\t" << requesterServiceName << std::endl;
00114   std::cerr << "\ttargetEntityName:\t" << targetEntityName << std::endl;
00115   std::cerr << "\ttargetServiceName:\t" << targetServiceName << std::endl;
00116   std::cerr << "\ttargetServiceInterfaceName:\t" << targetServiceInterfaceName << std::endl;
00117   std::cerr << "\trequestId:\t" << requestId << std::endl;*/
00118   
00119   
00120   // process the request
00121   try {
00122   
00123     //std::cerr << "\tgetServiceInterface" << std::endl;
00124     shared_ptr<ServiceInterface> si = getServiceInterface (targetServiceInterfaceName);
00125     
00126     if (si == false) {
00127       throw Exception ("Service::processServiceRequest : unknown Service Interface name: " + targetServiceInterfaceName);
00128     }
00129     
00130     //std::cerr << "\tprocessServiceRequest" << std::endl;
00131     shared_ptr<ServiceReply> reply = si->processServiceRequest (request);
00132     
00133     activeObject_->getCommunicationGateway()->sendServiceReply (targetService, requesterEntityName, requesterServiceName, reply);
00134     
00135   } // try
00136   catch (Exception &e) {
00137     std::cerr << "Service::processServiceRequest : caught an Exception while processing a Service Request : " << e.what() << std::endl;
00138     shared_ptr<ServiceReply> errorReply (new ServiceReply (request, e.what()));
00139     
00140     activeObject_->getCommunicationGateway()->sendServiceReply (targetService, requesterEntityName, requesterServiceName, errorReply);
00141     throw e;
00142   }
00143   catch (...) {
00144     std::cerr << "Service::processServiceRequest : caught an unknown exception while processing a Service Request " << std::endl;
00145     shared_ptr<ServiceReply> errorReply (new ServiceReply (request, "Unknown error."));
00146     
00147     activeObject_->getCommunicationGateway()->sendServiceReply (targetService, requesterEntityName, requesterServiceName, errorReply);
00148     throw Exception ("Service::processServiceRequest : caught an unknown exception");
00149   }
00150 }; // processServiceRequest()
00151 
00152 
00153 void Service::processServiceReply (shared_ptr<ServiceReply> reply)
00154 {
00155   //std::cerr << "Service::processServiceReply" << std::endl;
00156   //std::cerr << "\trequestId:\t" << reply->getRequestId() << std::endl;
00157   
00158   int requestId = reply->getRequestId();
00159   
00160   if (replyHandlerMap_.count (requestId) == 0) {
00161     std::cerr << "Service::processServiceReply : no handler for request with id: " << requestId << std::endl;;
00162   }
00163   else {
00164     shared_ptr<ServiceReplyHandlerMethodBase> h = replyHandlerMap_[requestId];
00165     if (h) {
00166       h->callHandler (reply);
00167     }
00168     else {
00169       std::cerr << "Service::processServiceReply : no handler for request with id: " << requestId << std::endl;;
00170     }
00171   }
00172   
00173   //unregister the original request
00174   unregisterOutgoingServiceRequest (requestId);
00175 }; // processServiceReply()
00176 
00177 
00178 void Service::processDataFeedInput (std::string producerEntityName, std::string producerServiceName, std::string dataFeedName, shared_ptr<DataBox> dataBox)
00179 {
00180 //     std::cerr << "Service::processDataFeedInput()" << std::endl;
00181   shared_ptr<DataFeedInputHandlerMethodBase> method = getDataFeedInputHandlerMethod (producerEntityName, producerServiceName, dataFeedName);
00182   method->callHandler (dataBox);
00183 }; // processDataFeedInput()
00184 
00185 void Service::addServiceInterface (shared_ptr<ServiceInterface> serviceInterface)
00186 {
00187   std::string serviceInterfaceName = serviceInterface->getServiceInterfaceDescription()->getServiceInterfaceName();
00188   
00189   //std::cerr << "Service::addServiceInterface : serviceName=\"" << serviceInstanceDescription_->getServiceInstanceName() << "\", interfaceName=\"" << serviceInterfaceName << "\"" << std::endl;
00190   
00191   if (serviceInterfaceMap_.find (serviceInterfaceName) != serviceInterfaceMap_.end()) {
00192     std::stringstream ss;
00193     ss << "Service::addServiceInterface : Service with serviceInstanceName=\"" << serviceInstanceDescription_->getServiceInstanceName() << "\" already has a ServiceInterface with serviceInterfaceName=\"" << serviceInterfaceName << "\"";
00194     throw Exception (ss.str());
00195   }
00196   
00197   serviceInterfaceMap_[serviceInterfaceName] = serviceInterface;
00198 }; // addServiceInterface()
00199 
00200 shared_ptr<ServiceInterface> Service::getServiceInterface (std::string serviceInterfaceName)
00201 {
00202   shared_ptr<ServiceInterface> si = serviceInterfaceMap_[serviceInterfaceName];
00203   
00204   if (si == false) {
00205     std::stringstream ss;
00206     ss << "Service::getServiceInterface : Service with serviceInstanceName=\"" << serviceInstanceDescription_->getServiceInstanceName() << "\" does not have a ServiceInterface with serviceInterfaceName=\"" << serviceInterfaceName << "\"";
00207     throw Exception (ss.str());
00208   }
00209   
00210   return si;
00211 }; // getServiceInterface()
00212 
00213 void Service::registerServiceInterfaceHandlerMethod (std::string serviceInterfaceName, shared_ptr<ServiceInterfaceHandlerMethodBase> handlerMethod)
00214 {
00215   //std::cerr << "Service::registerServiceRequestHandler(serviceName=" << serviceName << " handler=" << handler << ")" << std::endl;
00216   
00217   shared_ptr<ServiceInterface> si = getServiceInterface (serviceInterfaceName);
00218   
00219   if (si) {
00220     si->setHandlerMethod (handlerMethod);
00221   }
00222   else {
00223     throw Exception ("Service::registerServiceInterfaceHandler : no interface for name: " + serviceInterfaceName);
00224   }
00225 }; // registerServiceInterfaceHandler()
00226 
00227 std::vector<shared_ptr<ServiceTypeDescription> > Service::getServiceTypeDescriptions()
00228 {
00229   return serviceInstanceDescription_->getServiceTypeDescriptions();
00230 }; // getServiceDescription()
00231 
00232 shared_ptr<ServiceInstanceDescription> Service::getServiceInstanceDescription()
00233 {
00234   return serviceInstanceDescription_;
00235 }; // getServiceInstanceDescription()
00236 
00237 shared_ptr<ServiceConfiguration> Service::getServiceConfiguration()
00238 {
00239   return serviceConfiguration_;
00240 }; // getServiceConfiguration()
00241 
00242 shared_ptr<Entity> Service::getEntity()
00243 {
00244   return entity_;
00245 }; // getEntity()
00246 
00247 shared_ptr<ActiveObject> Service::getActiveObject()
00248 {
00249   return activeObject_;
00250 }; // getActiveObject()
00251 
00252 
00253 shared_ptr<ServiceRequest> Service::makeNewServiceRequest (std::string targetEntitytName, std::string targetServiceName, std::string targetServiceInterfaceName)
00254 {
00255   //std::cerr << "Service::makeNewServiceRequest(entitytName=" << targetEntitytName << ", servicName=" << targetServiceName << ", interfaceName=" << targetServiceInterfaceName << ")" << std::endl;
00256   
00257   
00258   //throw Exception("Service::makeNewServiceRequest : not implemented");
00259   
00260   shared_ptr<ServiceRequest> sr (new ServiceRequest (entity_->getEntityDescription()->getEntityName(), serviceInstanceDescription_->getServiceInstanceName(), targetEntitytName, targetServiceName, targetServiceInterfaceName, ++lastRequestId_));
00261   
00262   return sr;
00263   
00264 }; // makeNewServiceRequest()
00265 
00266 void Service::sendServiceRequest (shared_ptr<ServiceRequest> sr, shared_ptr<ServiceReplyHandlerMethodBase> replyHandlerMethod)
00267 {
00268   //std::cerr << "Service::sendServiceRequest(ServiceRequest=" << sr.get() << ")" << std::endl;
00269   
00270   if (!replyHandlerMethod) {
00271     replyHandlerMethod = shared_ptr<ServiceReplyHandlerMethodBase> (new ServiceReplyHandlerMethod<Service> (this, &Service::dummyHandler));
00272   }
00273   
00274   try {
00275     int requestId = sr->getRequestId();
00276     
00277     replyHandlerMap_[requestId] = replyHandlerMethod;
00278     
00279     shared_ptr<CommunicationGateway> commGateWay = activeObject_->getCommunicationGateway();
00280     
00281     std::string requesterServiceName = sr->getRequesterServiceName();
00282     
00283     shared_ptr<Service> requesterService = entity_->getService (serviceInstanceDescription_->getServiceInstanceName());
00284     registerOutgoingServiceRequest (sr);
00285     commGateWay->sendServiceRequest (requesterService, sr);
00286   }
00287   catch (Exception &e) {
00288     std::stringstream ss;
00289     ss << "Service Request Failed : ";
00290     ss << e.what();
00291     throw exceptions::ServiceRequestFailedException (ss.str());
00292   }
00293   
00294 }; // sendServiceRequest()
00295 
00296 void Service::addDataFeed (shared_ptr<DataFeed> dataFeed)
00297 {
00298   std::string dataFeedName = dataFeed->getDataFeedDescription()->getDataFeedName();
00299   
00300   std::cerr << "Service::addDataFeed : dataFeedName=\"" << serviceInstanceDescription_->getServiceInstanceName() << "\", dataFeedName=\"" << dataFeedName << "\"" << std::endl;
00301   
00302   if (dataFeedMap_.find (dataFeedName) != dataFeedMap_.end()) {
00303     std::stringstream ss;
00304     ss << "Service::addDataFeed : Service with serviceInstanceName=\"" << serviceInstanceDescription_->getServiceInstanceName() << "\" already has a DataFeed with dataFeedName=\"" << dataFeedName << "\"";
00305     throw Exception (ss.str());
00306   }
00307   
00308   dataFeedMap_[dataFeedName] = dataFeed;
00309 }; // addDataFeed()
00310 
00311 shared_ptr<DataFeed> Service::getDataFeed (std::string dataFeedName)
00312 {
00313   std::map<std::string, shared_ptr<DataFeed> >::iterator it = dataFeedMap_.find (dataFeedName);
00314   
00315   if (it == dataFeedMap_.end()) {
00316     std::stringstream ss;
00317     ss << "Service::getDataFeed : Service with serviceInstanceName=\"" << serviceInstanceDescription_->getServiceInstanceName() << "\" does not have a registered DataFeed with dataFeedName=\"" << dataFeedName << "\"";
00318     throw Exception (ss.str());
00319   };
00320   
00321   return (*it).second;
00322 }; // getDataFeed()
00323 
00324 shared_ptr<DataBox> Service::getDataBoxForDataFeed (std::string dataFeedName)
00325 {
00326   shared_ptr<DataFeed> df = dataFeedMap_[dataFeedName];
00327   
00328   if (df == false) {
00329     std::stringstream ss;
00330     ss << "Service::getDataBoxForDataFeed : DataFeed with dataFeedName=\"" << dataFeedName << "\" is not registered.";
00331     throw Exception (ss.str());
00332   }
00333   
00334   return DataFactory::buildDataBox (df->getDataFeedDescription()->getDataFeedOutputDataName());
00335 }; // getDataBoxForDataFeed()
00336 
00337 void Service::sendToDataFeed (std::string dataFeedName, shared_ptr<DataBox> dataBox)
00338 {
00339   shared_ptr<CommunicationGateway> commGateWay = activeObject_->getCommunicationGateway();
00340   std::string entityName = serviceInstanceDescription_->getEntityDescription()->getEntityName();
00341   std::string serviceName = serviceInstanceDescription_->getServiceInstanceName();
00342   commGateWay->sendToDataFeed (entityName, serviceName, dataFeedName, dataBox);
00343 }; // sendToDataFeed()
00344 
00345 void Service::registerDataFeedInputHandler (std::string producerEntityName, std::string producerServiceName, std::string dataFeedName, shared_ptr<DataFeedInputHandlerMethodBase> handlerMethod)
00346 {
00347   std::cerr << "Service::registerDataFeedInputHandler(producerEntityName=\"" << producerEntityName << "\", producerServiceName=\"" << producerServiceName << "\", dataFeedName=\"" << dataFeedName << "\"" << std::endl;
00348   
00349   if (dataFeedInputHandlerMap_[producerEntityName][producerServiceName][dataFeedName]) {
00350     std::stringstream ss;
00351     ss << "Service::registerDataFeedInputHandler : Service with serviceInstanceName=\"" << serviceInstanceDescription_->getServiceInstanceName() << "\" already has a handler for the data feed with producerEntityName=\"" << producerEntityName << "\", producerServiceName=\"" << producerServiceName << "\", dataFeedName=\"" << dataFeedName << "\"";
00352     throw Exception (ss.str());
00353   }
00354   
00355   std::map<std::string, std::map<std::string, shared_ptr<DataFeedInputHandlerMethodBase> > > entityMap = dataFeedInputHandlerMap_[producerEntityName];
00356   std::map<std::string, shared_ptr<DataFeedInputHandlerMethodBase> > serviceMap = entityMap[producerServiceName];
00357   serviceMap[dataFeedName] = handlerMethod;
00358   entityMap[producerServiceName] = serviceMap;
00359   dataFeedInputHandlerMap_[producerEntityName] = entityMap;
00360   
00361   std::string consumerEntityName = entity_->getEntityDescription()->getEntityName();
00362   std::string consumerServiceName = serviceInstanceDescription_->getServiceInstanceName();
00363   
00364   shared_ptr<CommunicationGateway> commGateWay = getActiveObject()->getCommunicationGateway();
00365 #ifdef USE_COMM
00366   shared_ptr<Task> setupTask (new YarpDataFeedSetupTask (entity_->getService (serviceInstanceDescription_->getServiceInstanceName()),
00367                               producerEntityName, producerServiceName, dataFeedName, getActiveObject()));
00368                               
00369 //      activeObject_->addTask(setupTask);
00370   commGateWay->addDataFeedSetupTask (setupTask);
00371   
00372   if (commGateWay->isNewDataFeedSetupTaskAvailable()) {
00373     activeObject_->addTask (commGateWay->getDataFeedSetupTask());
00374   }
00375 #endif
00376   commGateWay->connectToDataFeed (producerEntityName, producerServiceName, dataFeedName,
00377                                   entity_->getService (serviceInstanceDescription_->getServiceInstanceName()));
00378 };
00379 
00380 shared_ptr<DataFeedInputHandlerMethodBase> Service::getDataFeedInputHandlerMethod (std::string producerEntityName, std::string producerServiceName, std::string dataFeedName)
00381 {
00382   std::map<std::string, shared_ptr<DataFeedInputHandlerMethodBase> > dataFeedMap = dataFeedInputHandlerMap_[producerEntityName][producerServiceName];
00383   
00384   if (dataFeedMap.find (dataFeedName) == dataFeedMap.end()) {
00385     std::stringstream ss;
00386     ss << "Service::getDataFeedName : Service with serviceInstanceName=\"" << serviceInstanceDescription_->getServiceInstanceName() << "\" already has a handler for the data feed with producerEntityName=\"" << producerEntityName << "\", producerServiceName=\"" << producerServiceName << "\", dataFeedName=\"" << dataFeedName << "\"";
00387     throw Exception (ss.str());
00388   }
00389   
00390   return dataFeedMap[dataFeedName];
00391 }; // registerDataFeedInputHandler()
00392 
00393 void Service::registerOutgoingServiceRequest (shared_ptr<ServiceRequest> sr)
00394 {
00395   int reqId = sr->getRequestId();
00396   std::cerr << "Service::registerOutgoingServiceRequest : requestId=" << reqId << std::endl;
00397   if (outgoingRequestMap_.find (reqId) != (outgoingRequestMap_.end())) {
00398     std::stringstream ss;
00399     ss << "Service::registerOutgoingServiceRequest : ServiceRequest with id=" << reqId << " already registered";
00400     throw Exception (ss.str());
00401   }
00402   else {
00403     outgoingRequestMap_[reqId] = sr;
00404   }
00405 };
00406 
00407 void Service::unregisterOutgoingServiceRequest (int requestId)
00408 {
00409   std::cerr << "Service::unregisterOutgoingServiceRequest : requestId=" << requestId << std::endl;
00410   
00411   if (outgoingRequestMap_.find (requestId) != (outgoingRequestMap_.end())) {
00412     outgoingRequestMap_.erase (requestId);
00413   }
00414   else {
00415     std::stringstream ss;
00416     ss << "Service::unregisterOutgoingServiceRequest : requestId=" << requestId << " not registered";
00417     throw Exception (ss.str());
00418     
00419   }
00420 };
Generated on Fri Mar 4 22:14:58 2011 for MeRMaID::support by  doxygen 1.6.3