00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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 };
00088
00089
00090 Service::~Service()
00091 {
00092
00093 };
00094
00095
00096 void Service::update()
00097 {
00098
00099 };
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
00109 shared_ptr<Service> targetService = entity_->getService (serviceInstanceDescription_->getServiceInstanceName());
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 try {
00122
00123
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
00131 shared_ptr<ServiceReply> reply = si->processServiceRequest (request);
00132
00133 activeObject_->getCommunicationGateway()->sendServiceReply (targetService, requesterEntityName, requesterServiceName, reply);
00134
00135 }
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 };
00151
00152
00153 void Service::processServiceReply (shared_ptr<ServiceReply> reply)
00154 {
00155
00156
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
00174 unregisterOutgoingServiceRequest (requestId);
00175 };
00176
00177
00178 void Service::processDataFeedInput (std::string producerEntityName, std::string producerServiceName, std::string dataFeedName, shared_ptr<DataBox> dataBox)
00179 {
00180
00181 shared_ptr<DataFeedInputHandlerMethodBase> method = getDataFeedInputHandlerMethod (producerEntityName, producerServiceName, dataFeedName);
00182 method->callHandler (dataBox);
00183 };
00184
00185 void Service::addServiceInterface (shared_ptr<ServiceInterface> serviceInterface)
00186 {
00187 std::string serviceInterfaceName = serviceInterface->getServiceInterfaceDescription()->getServiceInterfaceName();
00188
00189
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 };
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 };
00212
00213 void Service::registerServiceInterfaceHandlerMethod (std::string serviceInterfaceName, shared_ptr<ServiceInterfaceHandlerMethodBase> handlerMethod)
00214 {
00215
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 };
00226
00227 std::vector<shared_ptr<ServiceTypeDescription> > Service::getServiceTypeDescriptions()
00228 {
00229 return serviceInstanceDescription_->getServiceTypeDescriptions();
00230 };
00231
00232 shared_ptr<ServiceInstanceDescription> Service::getServiceInstanceDescription()
00233 {
00234 return serviceInstanceDescription_;
00235 };
00236
00237 shared_ptr<ServiceConfiguration> Service::getServiceConfiguration()
00238 {
00239 return serviceConfiguration_;
00240 };
00241
00242 shared_ptr<Entity> Service::getEntity()
00243 {
00244 return entity_;
00245 };
00246
00247 shared_ptr<ActiveObject> Service::getActiveObject()
00248 {
00249 return activeObject_;
00250 };
00251
00252
00253 shared_ptr<ServiceRequest> Service::makeNewServiceRequest (std::string targetEntitytName, std::string targetServiceName, std::string targetServiceInterfaceName)
00254 {
00255
00256
00257
00258
00259
00260 shared_ptr<ServiceRequest> sr (new ServiceRequest (entity_->getEntityDescription()->getEntityName(), serviceInstanceDescription_->getServiceInstanceName(), targetEntitytName, targetServiceName, targetServiceInterfaceName, ++lastRequestId_));
00261
00262 return sr;
00263
00264 };
00265
00266 void Service::sendServiceRequest (shared_ptr<ServiceRequest> sr, shared_ptr<ServiceReplyHandlerMethodBase> replyHandlerMethod)
00267 {
00268
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 };
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 };
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 };
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 };
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 };
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
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 };
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 };