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.hpp 00024 * @Description Support Service declaration 00025 * @Status Work in Progress 00026 * @Version $Id: Service.hpp 1 2011-03-04 18:13:18Z jreis $ 00027 * @Maintainer Marco Barbosa 00028 */ 00029 00030 00031 #ifndef __SUPPORT_SERVICE_H 00032 #define __SUPPORT_SERVICE_H 00033 00034 namespace mermaid 00035 { 00036 namespace support 00037 { 00038 namespace service 00039 { 00040 class Service; 00041 } 00042 } 00043 } 00044 00045 #include <map> 00046 #include <vector> 00047 00048 #include <ActiveObject.hpp> 00049 00050 #include <Task.hpp> 00051 #include <XmlDocument.hpp> 00052 #include <Logger.hpp> 00053 00054 #include <DataFeed.hpp> 00055 //#include <DataFeedInputHandler.hpp> 00056 #include <DataFeedInputHandlerMethod.hpp> 00057 #include <ServiceConfiguration.hpp> 00058 #include <ServiceInstanceDescription.hpp> 00059 #include <ServiceTypeDescription.hpp> 00060 #include <ServiceTypeDescriptionRepository.hpp> 00061 #include <ServiceReplyHandlerMethod.hpp> 00062 #include <ServiceRequest.hpp> 00063 #include <ServiceRequestState.hpp> 00064 #include <ServiceReply.hpp> 00065 #include <ServiceInterface.hpp> 00066 #include <ServiceInterfaceHandlerMethod.hpp> 00067 00068 00069 namespace mermaid 00070 { 00071 namespace support 00072 { 00073 namespace service 00074 { 00075 using mermaid::support::activeobject::ActiveObject; 00076 using mermaid::support::activeobject::Task; 00077 using boost::shared_ptr; 00078 using mermaid::support::xml::XmlDocument; 00079 using mermaid::support::logging::Logger; 00080 00081 /** 00082 * @Class Service Service.hpp "Service.hpp" 00083 * @Description Service class. 00084 * 00085 * This is the base class of all services that will be running inside ActiveObjects. 00086 * @Author Marco Barbosa + Nelson Ramos 00087 */ 00088 class Service 00089 { 00090 friend class ServiceReplyDeliveryTask; 00091 friend class ServiceDataFeedDeliveryTask; 00092 friend class ServiceRequestDeliveryTask; 00093 00094 public: 00095 /** 00096 * @Description Constructor. This constructor must be called by the specific class's constructor. 00097 * @Author Marco Barbosa + Nelson Ramos 00098 */ 00099 //Service(shared_ptr<ActiveObject> ao, shared_ptr<XmlDocument> serviceDescription, shared_ptr<ServiceTypeDescriptionRepository> serviceTypeDescriptionRepository); 00100 Service (shared_ptr<ActiveObject> ao, shared_ptr<Entity> entity, shared_ptr<ServiceInstanceDescription> serviceInstanceDescription, shared_ptr<ServiceConfiguration> serviceConfiguration); 00101 00102 /** 00103 * @Description Destructor 00104 * @Author Marco Barbosa + Nelson Ramos 00105 */ 00106 virtual ~Service(); 00107 00108 00109 /** 00110 * @Description Method that is called regularly by the ServiceUpdateTask 00111 * 00112 * This method is called by the ServiceUpdateTask at a rate which is defined in the Service instance's ServiceConfiguration 00113 * @Author Marco Barbosa + Nelson Ramos 00114 */ 00115 00116 virtual void update(); 00117 00118 00119 /** 00120 * @Description Service initializer method. 00121 * 00122 * Method that will be called when the Service is ready for user initializations. 00123 * @Author Marco Barbosa 00124 */ 00125 virtual void initialize() = 0; 00126 00127 //user usable stuff 00128 00129 //request stuff 00130 /** 00131 * @Description Creates a new ServiceRequest. 00132 * 00133 * This method is used to build a new ServiceRequest to be sent to the specified target. 00134 * @Argument targetEntityName The name of the Entity in which the target Service is located. 00135 * @Argument targetServiceName The name of the target Service. 00136 * @Argument targetServiceInterfaceName The name of the ServiceInterface to which the ServiceRequest should be delivered. 00137 * @Returns A ServiceRequest configured to be sent to the specified target ServiceInterface 00138 * @Author Marco Barbosa 00139 */ 00140 shared_ptr<ServiceRequest> makeNewServiceRequest (std::string targetEntityName, std::string targetServiceName, std::string targetServiceInterfaceName); 00141 00142 /** 00143 * @Description Sends a ServiceRequest 00144 * 00145 * This method is used to send a ServiceRequest which was previously built using the makeNewServiceRequest method and to define a handler in which he corresponding ServiceReply will be handled. 00146 * @Argument serviceRequest The ServiceRequest to be sent (the Service to which it will be delivered was already defined in the makeNewServiceRequest method) 00147 * @Argument replyHandler The handler for the ServiceReply 00148 * @Throws ServiceRequestFailedException Throws ServiceRequestFailedException whenever it is impossible to send the Service Request. 00149 * @Author Marco Barbosa 00150 */ 00151 void sendServiceRequest ( 00152 shared_ptr<ServiceRequest> serviceRequest, 00153 shared_ptr<ServiceReplyHandlerMethodBase> replyHandlerMethod 00154 = shared_ptr<ServiceReplyHandlerMethodBase>()); 00155 00156 /** 00157 * @Description Registers a ServiceInterfaceHandler. 00158 * 00159 * This method is used to define the handler for a Service's ServiceInterface. 00160 * The available interfaces are defined in the ServiceTypeDescription XML file. 00161 * @Argument serviceInterfaceName The name of the interface for which to register the handler 00162 * @Argument handler The handler for this ServiceInterface 00163 * @Author Marco Barbosa 00164 */ 00165 void registerServiceInterfaceHandlerMethod (std::string serviceInterfaceName, shared_ptr<ServiceInterfaceHandlerMethodBase> handlerMethod); 00166 00167 /** 00168 * @Description Registers a DataFeedInputHandler. 00169 * 00170 * This method is used to register a DataFeedInputHandler for a specified DataFeed. 00171 * @Argument producerEntityName The name of the Entity in which the producer Service is located. 00172 * @Argument producerServiceName The name of the producer Service. 00173 * @Argument dataFeedName The name of the DataFeed for which this handler will handle data. 00174 * @Argument handlerMethod The DataFeedInputHandlerHandlerMethod which points to the handler method to be called upon reception of the data. 00175 * @Author Marco Barbosa 00176 */ 00177 void registerDataFeedInputHandler (std::string producerEntityName, std::string producerServiceName, std::string dataFeedName, shared_ptr<DataFeedInputHandlerMethodBase> handlerMethod); 00178 00179 /** 00180 * @Description Method used to send data to a DataFeed 00181 * 00182 * This method is used to send data to a DataFeed owned by the Service. 00183 * The available DataFeed are specified in the ServiceTypeDescription XML file. 00184 * @Argument dataFeedName The name of the local DataFeed to which the data is going to be sent. 00185 * @Argument dataBox DataBox with the data that is going to be sent to the data feed. This DataBox must have been obtained using the getDataBoxForDataFeed method. 00186 * @Author Marco Barbosa 00187 */ 00188 void sendToDataFeed (std::string dataFeedName, shared_ptr<DataBox> dataBox); 00189 00190 /** 00191 * @Description DataBox builder for a specific DataFeed. 00192 * 00193 * This method builds a DataBox formatted according to the defined data format of the specified DataFeed 00194 * @Argument dataFeedName The name of the DataFeed with which this DataBox should be compatible 00195 * @Returns A DataBox correctly formatted for the specified DataFeed.. 00196 * @Author Marco Barbosa 00197 */ 00198 shared_ptr<DataBox> getDataBoxForDataFeed (std::string dataFeedName); 00199 00200 /** 00201 * @Description ServiceTypeDescription getter. 00202 * 00203 * This method returns the ServiceTypeDescription of the Service. 00204 * @Returns ServiceTypeDescription of the Service. 00205 * @Author Marco Barbosa 00206 */ 00207 virtual std::vector<shared_ptr<ServiceTypeDescription> > getServiceTypeDescriptions(); 00208 00209 /** 00210 * @Description ServiceInstanceDescription getter. 00211 * 00212 * This method returns the ServiceInstanceDescription of the Service. 00213 * @Returns ServiceInstanceDescription of the Service 00214 * @Author Marco Barbosa 00215 */ 00216 virtual shared_ptr<ServiceInstanceDescription> getServiceInstanceDescription(); 00217 00218 /** 00219 * @Description ServiceConfiguration getter. 00220 * 00221 * This method returns the ServiceConfiguration of the Service. 00222 * @Returns ServiceConfiguration of the Service 00223 * @Author Marco Barbosa 00224 */ 00225 virtual shared_ptr<ServiceConfiguration> getServiceConfiguration(); 00226 00227 /** 00228 * @Description Entity getter. 00229 * 00230 * This method returns the Entity to which the Service belongs. 00231 * @Returns Entity to which the Service belongs. 00232 * @Author Marco Barbosa 00233 */ 00234 virtual shared_ptr<Entity> getEntity(); 00235 00236 /** 00237 * @Description ActiveObject getter. 00238 * 00239 * This method returns the ActiveObject in which the Service is running. 00240 * @Returns ActiveObject in which the Service is running. 00241 * @Author Marco Barbosa 00242 */ 00243 shared_ptr<ActiveObject> getActiveObject(); 00244 00245 //! @TODO Make these methods protected. 00246 void addServiceInterface (shared_ptr<ServiceInterface> serviceInterface); 00247 void addDataFeed (shared_ptr<DataFeed> dataFeed); 00248 00249 protected: 00250 /** 00251 * @Description Service Logger getter. 00252 * 00253 * This method returns the Service Logger. 00254 * Use this logger for error and reporting purposes only. 00255 * @Returns Service Logger. 00256 * @Author Joao Reis 00257 */ 00258 const shared_ptr<Logger>& logger() const; 00259 00260 /** 00261 * @Description Quickly log a message. 00262 * 00263 * @Author Joao Reis 00264 */ 00265 void logger (const std::string& msg) const; 00266 00267 /** 00268 * @Description Service Debug Logger getter. 00269 * 00270 * This method returns the Service Debug Logger. 00271 * Use this logger for debugging purposes only. 00272 * @Returns Service Logger. 00273 * @Author Joao Reis 00274 */ 00275 const shared_ptr<Logger>& debug() const; 00276 00277 /** 00278 * @Description Quickly log a debug message. 00279 * 00280 * @Author Joao Reis 00281 */ 00282 void debug (const std::string& msg) const; 00283 00284 private: 00285 //mermaid internal stuff 00286 shared_ptr<ServiceInterface> getServiceInterface (std::string serviceInterfaceName); 00287 void processServiceRequest (shared_ptr<ServiceRequest> request); 00288 void processServiceReply (shared_ptr<ServiceReply> reply); 00289 void processDataFeedInput (std::string producerEntityName, std::string producerServiceName, std::string dataFeedName, shared_ptr<DataBox> dataBox); 00290 00291 //data-feed stuff 00292 shared_ptr<DataFeed> getDataFeed (std::string dataFeedName); 00293 //DataFeedInputHandler getDataFeedInputHandler(std::string producerEntityName, std::string producerServiceName, std::string dataFeedName); 00294 shared_ptr<DataFeedInputHandlerMethodBase> getDataFeedInputHandlerMethod (std::string producerEntityName, std::string producerServiceName, std::string dataFeedName); 00295 00296 private: 00297 00298 // Service's used domain objects of the ServiceFramework 00299 shared_ptr<Entity> entity_; 00300 shared_ptr<ServiceInstanceDescription> serviceInstanceDescription_; 00301 shared_ptr<ServiceConfiguration> serviceConfiguration_; 00302 std::map<std::string, shared_ptr<ServiceInterface> > serviceInterfaceMap_; // maps service interface names to service interfaces 00303 std::map<std::string, shared_ptr<DataFeed> > dataFeedMap_; 00304 00305 //service reply handler maps 00306 std::map<int, shared_ptr<ServiceReplyHandlerMethodBase> > replyHandlerMap_; 00307 00308 //data feed handler maps 00309 00310 // producerEntityName -> producerServiceName -> dataFeedName -> countedptr<handlerMethod> 00311 std::map<std::string, std::map<std::string, std::map<std::string, shared_ptr<DataFeedInputHandlerMethodBase> > > > dataFeedInputHandlerMap_; 00312 00313 shared_ptr<ActiveObject> activeObject_; 00314 shared_ptr<Task> serviceUpdateTask_; 00315 int lastRequestId_; 00316 00317 //service request map 00318 std::map<int, shared_ptr<ServiceRequest> > outgoingRequestMap_; 00319 void registerOutgoingServiceRequest (shared_ptr<ServiceRequest> request); 00320 void unregisterOutgoingServiceRequest (int requestId); 00321 00322 static shared_ptr<ServiceTypeDescriptionRepository> serviceTypeDescriptionRepository_; 00323 00324 // logger 00325 shared_ptr<Logger> logger_; 00326 shared_ptr<Logger> debugLogger_; 00327 00328 // Dummy handler, used internally for requests that don't 00329 // need an answer 00330 void dummyHandler (shared_ptr<ServiceReply> reply) {} 00331 }; // Service 00332 00333 inline const shared_ptr<Logger>& Service::logger() const 00334 { 00335 return logger_; 00336 } 00337 inline void Service::logger (const std::string& msg) const 00338 { 00339 logger_->step (msg); 00340 } 00341 inline const shared_ptr<Logger>& Service::debug() const 00342 { 00343 return debugLogger_; 00344 } 00345 inline void Service::debug (const std::string& msg) const 00346 { 00347 debugLogger_->step (msg); 00348 } 00349 } // namespace service 00350 } // namespace support 00351 } // namespace mermaid 00352 00353 #endif // __SUPPORT_SERVICE_H