RSB  0.17.0
RemoteServer.cpp
Go to the documentation of this file.
1 /* ============================================================
2  *
3  * This file is a part of RSB project
4  *
5  * Copyright (C) 2010 by Johannes Wienke <jwienke at techfak dot uni-bielefeld dot de>
6  * 2011 Jan Moringen <jmoringe@techfak.uni-bielefeld.de>
7  *
8  * This file may be licensed under the terms of the
9  * GNU Lesser General Public License Version 3 (the ``LGPL''),
10  * or (at your option) any later version.
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the LGPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the LGPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * The development of this software was supported by:
23  * CoR-Lab, Research Institute for Cognition and Robotics
24  * Bielefeld University
25  *
26  * ============================================================ */
27 
28 #include "RemoteServer.h"
29 
30 #include <boost/format.hpp>
31 
32 #include <rsc/misc/UUID.h>
33 
34 #include "../EventId.h"
35 #include "../MetaData.h"
36 #include "../Factory.h"
37 
38 #include "../filter/MethodFilter.h"
39 
40 using namespace std;
41 
42 using namespace boost;
43 
44 using namespace rsc::runtime;
45 using namespace rsc::logging;
46 using namespace rsc::threading;
47 
48 namespace rsb {
49 namespace patterns {
50 
51 // RemoteMethod
52 
53 RemoteServer::RemoteMethod::RemoteMethod(const Scope& scope,
54  const std::string& name,
55  const ParticipantConfig& listenerConfig,
56  const ParticipantConfig& informerConfig)
57  : Method(scope, name, listenerConfig, informerConfig),
58  logger(Logger::getLogger(boost::str(boost::format("rsb.patterns.RemoteMethod[%1%]")
59  % name))) {
60 }
61 
63 }
64 
66  return "remote-method";
67 }
68 
71  listener->addFilter(filter::FilterPtr(new filter::MethodFilter("REPLY")));
72  listener->addHandler(shared_from_this());
73  return listener;
74 }
75 
77  EventPtr request) {
78  FuturePtr result(new Future<EventPtr>());
79 
80  {
81  MutexType::scoped_lock lock(this->inprogressMutex);
82 
83  request->setScopePtr(getInformer()->getScope());
84  request->setMethod("REQUEST");
85  getInformer()->publish(request);
86 
87  this->inprogress.insert(std::make_pair(request->getId(), result));
88  }
89 
90  return result;
91 }
92 
94  if (!event || event->getCauses().empty()) {
95  RSCTRACE(logger, "Received uninteresting event " << event);
96  return;
97  }
98 
99  EventId requestId = *event->getCauses().begin();
101  {
102  MutexType::scoped_lock lock(this->inprogressMutex);
103  map<EventId, FuturePtr>::const_iterator it
104  = this->inprogress.find(requestId);
105  if (it != this->inprogress.end()) {
106  result = it->second;
107  this->inprogress.erase(requestId);
108  }
109  }
110 
111  if (!result) {
112  RSCTRACE(this->logger, "Received uninteresting event " << event);
113  return;
114  }
115  RSCDEBUG(this->logger, "Received reply event " << event);
116 
117  if (event->mutableMetaData().hasUserInfo("rsb:error?")) {
118  assert(event->getType() == typeName<std::string>());
119  result->setError(boost::str(boost::format("Error calling remote method '%1%': %2%")
120  % "TODO: obtain method name"
121  % *(boost::static_pointer_cast<string>(event->getData()))));
122  } else {
123  result->set(event);
124  }
125 }
126 
127 // RemoteServer
128 
132  : Participant(scope, listenerConfig), // TODO do this properly
133  logger(Logger::getLogger(str(format("rsb.patterns.RemoteServer[%1%]")
134  % scope.toString()))),
135  listenerConfig(listenerConfig), informerConfig(informerConfig) {
136  // TODO check that this server is alive...
137  // TODO probably it would be a good idea to request some method infos from
138  // the server, e.g. for type checking
139 }
140 
142  for (std::map<std::string, RemoteMethodPtr>::iterator it
143  = this->methods.begin(); it != this->methods.end(); ++it) {
144  it->second->deactivate();
145  }
146 }
147 
148 std::string RemoteServer::getKind() const {
149  return "remote-server";
150 }
151 
152 const std::set<std::string> RemoteServer::getTransportURLs() const {
153  return std::set<std::string>();
154 }
155 
157 
158  boost::mutex::scoped_lock lock(this->methodsMutex);
159 
160  if (this->methods.find(name) == this->methods.end()) {
161  RemoteMethodPtr method
162  = getFactory().createRemoteMethod(getScope()->concat(Scope("/" + name)),
163  this->listenerConfig,
164  this->informerConfig,
165  shared_from_this());
166 
167  method->activate();
168 
169  this->methods[name] = method;
170  }
171 
172  return this->methods[name];
173 
174 }
175 
176 RemoteServer::FuturePtr RemoteServer::callAsync(const std::string& methodName,
177  EventPtr request) {
178  RSCDEBUG(this->logger, "Calling method " << methodName << " with request " << request);
179 
180  // TODO check that the requested method exists
181  return getMethod(methodName)->call(methodName, request);
182 }
183 
184 EventPtr RemoteServer::call(const string& methodName,
185  EventPtr request,
186  unsigned int maxReplyWaitTime) {
187  return callAsync(methodName, request)->get(maxReplyWaitTime);
188 }
189 
190 }
191 }
virtual const std::set< std::string > getTransportURLs() const
TODO.
ListenerPtr listener
Definition: Server.h:120
ParticipantConfig listenerConfig
Definition: RemoteServer.h:282
std::map< std::string, RemoteMethodPtr > methods
Definition: RemoteServer.h:286
boost::shared_ptr< RemoteMethod > RemoteMethodPtr
Definition: RemoteServer.h:115
FuturePtr call(const std::string &methodName, EventPtr request)
std::map< EventId, FuturePtr > inprogress
Definition: RemoteServer.h:108
RemoteMethodPtr getMethod(const std::string &name)
Objects of this class participate in the exchange of notifications on one channel of the bus...
Definition: Participant.h:65
STL namespace.
RemoteServer(const Scope &scope, const ParticipantConfig &listenerConfig, const ParticipantConfig &informerConfig)
Construct a new RemoteServer object which can be used to call methods of the server at scope...
boost::shared_ptr< Filter > FilterPtr
ParticipantConfig listenerConfig
Definition: Server.h:117
Factory & getFactory()
Returns a factory for client-level RSB objects.
Definition: Factory.cpp:163
This filter matches events based on the value of their method field.
Definition: MethodFilter.h:42
void handle(EventPtr event)
Handle event.
boost::shared_ptr< Listener > ListenerPtr
Definition: Listener.h:155
virtual std::string getKind() const
Return the kind of the participant.
InformerBasePtr getInformer()
Returns the Informer participant, creating it if necessary.
Definition: Server.cpp:85
virtual ListenerPtr makeListener()
Creates and returns the Listener participant.
Definition: Server.cpp:80
Base class for method classes.
Definition: Server.h:55
patterns::RemoteServer::RemoteMethodPtr createRemoteMethod(const Scope &scope, const ParticipantConfig &listenerConfig=getFactory().getDefaultParticipantConfig(), const ParticipantConfig &informerConfig=getFactory().getDefaultParticipantConfig(), ParticipantPtr parent=ParticipantPtr())
Creates a patterns::RemoteServer::RemoteMethod.
Definition: Factory.cpp:374
virtual std::string getKind() const
Return the kind of the participant.
ParticipantConfig informerConfig
Definition: Server.h:118
ParticipantConfig informerConfig
Definition: RemoteServer.h:283
A class describing the configuration of Participant instances.
EventPtr call(const std::string &methodName, EventPtr data, unsigned int maxReplyWaitTime=25)
Call the method named methodName on the remote server, passing it the event data as argument and retu...
A unique ID for events in RSB.
Definition: EventId.h:48
ScopePtr getScope() const
Returns the scope of this participant.
Definition: Participant.cpp:64
rsc::logging::LoggerPtr logger
Definition: RemoteServer.h:280
boost::shared_ptr< Event > EventPtr
Definition: Event.h:264
boost::shared_ptr< FutureType > FuturePtr
Definition: RemoteServer.h:64
ListenerPtr makeListener()
Creates and returns the Listener participant.
Scope is a descriptor for a hierarchical channel of the unified bus.
Definition: Scope.h:46
FuturePtr callAsync(const std::string &methodName, EventPtr data)
Call the method named methodName on the remote server, passing it the event data as argument and retu...