IceManager.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXCore::core
19 * @author Nils Adermann (naderman at naderman dot de)
20 * @author Jan Issac (jan dot issac at gmx dot de)
21 * @date 2010
22 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
23 * GNU General Public License
24 */
25
26#pragma once
27
28#include <stdexcept> // for out_of_range
29#include <string> // for string, allocator, etc
30#include <typeinfo> // for type_info
31#include <utility> // for pair
32#include <vector> // for vector
33
34#include <Ice/Object.h> // for ObjectPtr
35#include <Ice/Properties.h> // for upCast
36#include <Ice/Proxy.h> // for ObjectPrx
37#include <IceUtil/Handle.h> // for Handle, HandleBase
38#include <IceUtil/Shared.h> // for Shared
39
40#include <ArmarXCore/core/logging/Logging.h> // for Logging
41#include <ArmarXCore/core/system/ImportExport.h> // for ARMARXCORE_IMPORT_EXPORT
43
44namespace Ice
45{
46 class ConnectionRefusedException;
47
48 class Communicator;
49 typedef ::IceInternal::Handle<::Ice::Communicator> CommunicatorPtr;
50
51 class ObjectAdapter;
52 typedef ::IceInternal::Handle<::Ice::ObjectAdapter> ObjectAdapterPtr;
53
54} // namespace Ice
55
57{
58 class Registry;
59}
60
61namespace IceProxy::IceStorm
62{
63 class TopicManager;
64 class Topic;
65} // namespace IceProxy::IceStorm
66
67namespace IceStorm
68{
71} // namespace IceStorm
72
73namespace IceGrid
74{
76}
77
78/**
79 * \namespace armarx
80 * The standard namespace for all classes and components within the ArmarXCore package
81 */
82namespace armarx
83{
84 class IceGridAdmin;
86
87 class IceManager;
88
89 /**
90 * IceManager smart pointer
91 */
93
94 /**
95 * Object handles pair which contains the object proxy and its adapter
96 */
97 using ObjectHandles = std::pair<Ice::ObjectPrx, Ice::ObjectAdapterPtr>;
98
99 /**
100 * @class IceManager
101 * @brief The IceManager class provides simplified access to commonly used Ice features.
102 * @ingroup DistributedProcessingSub
103 * @see Logging
104 */
105 class ARMARXCORE_IMPORT_EXPORT IceManager : public IceUtil::Shared, virtual public Logging
106 {
107 friend class Component;
108
109 public:
110 /**
111 * Set up an instance of this class with a preexisting communicator.
112 *
113 * This is useful for creating an instance from within an
114 * Ice::Application. If you do not have a communicator yet you can
115 * use one of the static factory methods instead.
116 *
117 * @param communicator An Ice communicator
118 *
119 * @param name A unique name, e.g. the base component's
120 * name. This name is used to create
121 * IceGridObservers, which must have a unique
122 * name.
123 * @param topicSuffix Suffix appended to all topic names.
124 */
125 IceManager(const Ice::CommunicatorPtr& communicator,
126 std::string name = "",
127 const std::string topicSuffix = "");
128
129 ~IceManager() override;
130
131 /**
132 * Register an object with Ice for being accessed through IceGrid.
133 *
134 * @param object The object to be registered, implementing an
135 * Ice interface.
136 *
137 * @param objectName The name this object should be available as.
138 *
139 * @return The registered object proxy.
140 */
141 ObjectHandles registerObject(const Ice::ObjectPtr& object,
142 const std::string& objectName,
143 const Ice::ObjectAdapterPtr& adapterToAddTo = nullptr);
144
145 /**
146 * Removes an object from the IceGrid
147 *
148 * @param objectName The name of the object that should be removed
149 */
150 void removeObject(const std::string& objectName);
151
152 /**
153 * Retrieves a proxy object.
154 *
155 * @param name Proxy name, e.g. Log
156 * @param endpoints The endpoints, e.g. tcp ‑p 10002
157 *
158 * @return A proxy of the remote instance.
159 */
160 template <class ProxyType>
162 getProxy(const std::string& name, const std::string& endpoints = std::string())
163 {
164 std::string proxyString = name;
165
166 if (!endpoints.empty())
167 {
168 proxyString += std::string(":") + endpoints;
169 }
170
171 std::string proxyTypedId =
172 proxyString + std::string(":") + std::string(typeid(ProxyType).name());
173
174 try
175 {
176 return ProxyType::uncheckedCast(implGetCheckedProxy(proxyTypedId));
177 }
178 catch (std::out_of_range& uncheckedProxiesException)
179 {
180 }
181
182 Ice::ObjectPrx base = communicator_stringToProxy(proxyString);
183
184 ProxyType proxy;
185
186 try
187 {
188 proxy = ProxyType::checkedCast(base);
189 implSetCheckedProxy(proxyTypedId, proxy);
190 }
191 catch (const Ice::ConnectionRefusedException&)
192 {
193 std::stringstream exceptionText;
194 exceptionText << "Connection refused for proxy of type '"
195 << GetTypeString<ProxyType>() << "': " << name
196 << " ProxyString: " << proxyString << " Endpoints: " << endpoints
197 << std::endl;
198 throwUserException(exceptionText.str());
199 }
200
201 if (!proxy)
202 {
203 std::stringstream exceptionText;
204 exceptionText << "Invalid Proxy. Searched for: " << name
205 << " ProxyString: " << proxyString << " Endpoints: " << endpoints
206 << std::endl;
207 throwUserException(exceptionText.str());
208 }
209
210 return proxy;
211 }
212
213 void throwUserException(std::string const& message);
214
215 /**
216 * @brief This functions removes the given proxy from the proxy cache.
217 * This is useful if the cached proxy became invalid.
218 * @param name Proxy name, e.g. Log
219 * @param endpoints The endpoints, e.g. tcp ‑p 10002
220 * @return True, if the proxy was found and removed.
221 */
222 template <class ProxyType>
223 bool
224 removeProxyFromCache(const std::string& name, const std::string& endpoints = std::string())
225 {
226 return removeProxyFromCache(name, typeid(ProxyType).name(), endpoints);
227 }
228
229 bool removeProxyFromCache(const std::string& name,
230 const std::string& typeName,
231 const std::string& endpoints = std::string());
232
233 /**
234 * @brief This functions removes the given proxy from the proxy cache.
235 * This is useful if the cached proxy became invalid.
236 * @param name Proxy name, e.g. Log
237 * @param endpoints The endpoints, e.g. tcp ‑p 10002
238 * @return True, if the proxy was found and removed.
239 */
240 bool removeProxyFromCache(const Ice::ObjectPrx& proxy);
241
242 /**
243 * Provides access to the Ice Storm Topic Manager.
244 * A proxy is created if necessary.
245 *
246 * @return A proxy of the IceStorm TopicManager.
247 */
248 IceStorm::TopicManagerPrx getTopicManager();
249 static IceStorm::TopicManagerPrx GetTopicManager(Ice::CommunicatorPtr communicator);
250
251 /**
252 * Gets an Ice Storm topic for publishing messages.
253 *
254 * @param topicName The name of the topic to publish on.
255 *
256 * @return A proxy of the topic's remote instance.
257 */
258 template <class TopicProxy>
259 TopicProxy
260 getTopic(const std::string& topicName, bool useUDP = false)
261 {
262 Ice::ObjectPrx pub = __getTopic(topicName, useUDP);
263 TopicProxy castTopic = TopicProxy::uncheckedCast(pub);
264
265 return castTopic;
266 }
267
268 /**
269 * Subscribe an object to a particular Ice Storm topic.
270 * If the object is already subscribed to the topic, it will be unsubscribed before.
271 * This is necessary to circumvent the usage from outdated subscriptions due to
272 * unproper exits.
273 *
274 * @param subcriber A proxy of the object to be subscribed,
275 * implementing the interface for listening on this
276 * topic
277 * @param topicName The topic's name
278 * @param orderedPublishing If true, the order of topic calls is ensured. This
279 * might decrease performance.
280 */
281 void subscribeTopic(Ice::ObjectPrx subscriber,
282 const std::string& topicName,
283 bool orderedPublishing = false);
284 void registerAndSubscribeTopic(Ice::ObjectPtr subscriber,
285 const std::string& topicName,
286 bool orderedPublishing = false);
287
288 /**
289 * Unsubscribe a given subscriber from a given topic
290 *
291 * @param subscriberProxy of the subscriber
292 * @param topicName The name of the subscribed topic.
293 */
294 void unsubscribeTopic(Ice::ObjectPrx subscriberProxy, const std::string& topicName);
295
296 /**
297 * Registers a specified object that is required before
298 * activating the endpoints.
299 *
300 * @param registrantName Object that has a dependency
301 * @param dependecyObjectName Dependecy object name
302 *
303 *
304 * @throw ObjectAlreadyActiveException
305 */
306 void registerObjectDependency(const std::string& registrantName,
307 const std::string& dependencyObjectName);
308
309 /**
310 * Registers a delayed topic subscription.
311 *
312 * @param registrantName Registrant object name
313 * @param topicName The topic name that should be subscribed
314 * later on
315 */
316 void registerDelayedTopicSubscription(const std::string& registrantName,
317 const std::string& topicName);
318
319 /**
320 * Registers a delayed topic retrieval.
321 *
322 * @param registrantName Registrant object name
323 * @param topicName The topic name
324 */
325 void registerDelayedTopicRetrieval(const std::string& registrantName,
326 const std::string& topicName);
327
328 /**
329 * @brief creates a proxy to the object specified with parameter objectName
330 * and tries to ping it.
331 * @param objectName Name of the object that should be checked
332 * @return true, if reachable
333 */
334 bool isObjectReachable(std::string objectName);
335
336 /**
337 * @brief creates a proxy to the object specified with parameter objectName
338 * and tries to ping it.
339 * @param objectName Name of the object that should be checked
340 * @return true, if reachable
341 */
342 template <typename ProxyType>
343 bool isObjectReachable(std::string objectName);
344
345 /**
346 * Short helper method to return the Ice Communicator.
347 *
348 * Uses static communicator() method
349 */
350 const Ice::CommunicatorPtr& getCommunicator();
351
352 /**
353 * Provides access to the IceGrid Registry. A proxy is created if
354 * necessary.
355 *
356 * @return A proxy of the IceGrid Registy.
357 */
358 IceGrid::RegistryPrx getIceGridRegistry();
359
360 /**
361 * Provides access to the IceGrid AdminSession via IceGridAdmin.
362 *
363 * @return The IceGrid AdminSession.
364 */
365 const armarx::IceGridAdminPtr& getIceGridSession();
366
367 /**
368 * Sets the session name
369 */
370 void setName(std::string name);
371
372 /**
373 * Removes all component objects and topics and shuts down the
374 * communicator.
375 */
376 void shutdown();
377
378 /**
379 * Waits until all invoked operation has been processed
380 */
381 void waitForShutdown();
382
383 /**
384 * Determines whether the communicator is shutdown.
385 */
386 bool isShutdown();
387
388 /**
389 * Destroys the communicator
390 */
391 void destroy();
392
393 /**
394 * @brief Get the suffix that is appended to all topics.
395 */
396 std::string getTopicSuffix() const;
397
398 private:
399 Ice::ObjectPrx communicator_stringToProxy(std::string const& proxyString);
400
401 Ice::ObjectPrx __getTopic(const std::string& topicName, bool useUDP = false);
402
403 struct ObjectEntry;
404
405 struct DependencyObjectEntry : public IceUtil::Shared
406 {
407 DependencyObjectEntry(std::string name, Ice::ObjectPrx proxy) :
408 name(name), proxy(proxy), resolved(false)
409 {
410 }
411
412 std::string name;
413 Ice::ObjectPrx proxy;
414 bool resolved;
415 };
416
417 using ObjectEntryPtr = IceUtil::Handle<ObjectEntry>;
418 using DependencyObjectEntryPtr = IceUtil::Handle<DependencyObjectEntry>;
419
420 using TopicList = std::vector<std::string>;
421 using DependencyList = std::vector<DependencyObjectEntryPtr>;
422
423 /**
424 * Subscribes all topics registered for a delayed subscription
425 */
426 void subscribeTopics(Ice::ObjectPrx subscriber,
427 const TopicList& topics,
428 bool orderedPublishing = false);
429
430 /**
431 * gets all topics registered for a delayed retrieval
432 */
433 void retrieveTopics(const TopicList& topics);
434
435 /**
436 * Check the existence of required servants.
437 *
438 * @return True if all servant objects exist, otherise false
439 */
440 void resolveObjectDependencies();
441
442 /**
443 * Returns the requested object entry if exists, otherwise
444 * a new entry is created and return.
445 *
446 * @param objectName Object name of the entry
447 *
448 * @return Smart pointer of the requested ObjectEntry.
449 */
450 ObjectEntryPtr getOrCreateObjectEntry(const std::string& objectName);
451
452 /**
453 * Cleans up all current IceStorm connections.
454 */
455 void cleanUp();
456
457 /**
458 * Retrieves an Ice Storm topic from the topic manager if necessary.
459 * Proxies are cached.
460 *
461 * @param topicName The name of the topic to publish on.
462 *
463 * @return A generic proxy instance of the topic. Has to be cast for
464 * actual messages to be sent.
465 */
466 IceStorm::TopicPrx retrieveTopic(const std::string& topicName);
467
468 /**
469 * Retrieves an Ice Storm topic from the topic manager if necessary.
470 * Proxies are cached.
471 *
472 * @param topicName The name of the topic to publish on.
473 *
474 * @return A generic proxy instance of the topic. Has to be cast for
475 * actual messages to be sent.
476 *
477 * @deprecated Use IceManager::retrieveTopic() instead
478 */
479 IceStorm::TopicPrx stormTopicRetrieve(const std::string& topicName);
480
481 Ice::ObjectPrx implGetCheckedProxy(std::string const& proxyTypedId);
482 void implSetCheckedProxy(std::string const& proxyTypedId, Ice::ObjectPrx const& proxy);
483
484
485 struct Impl;
486 std::unique_ptr<Impl> impl;
487 };
488
489 template <typename ProxyType>
490 bool
491 IceManager::isObjectReachable(std::string objectName)
492 {
493 try
494 {
495 ProxyType prx = getProxy<ProxyType>(objectName);
496 prx->ice_timeout(500)->ice_ping();
497 // if ping'able, object is already registered
498 return true;
499 }
500 catch (...)
501 {
502
503 return false;
504 }
505 }
506
507} // namespace armarx
#define ARMARXCORE_IMPORT_EXPORT
TopicProxy getTopic(const std::string &topicName, bool useUDP=false)
Gets an Ice Storm topic for publishing messages.
Definition IceManager.h:260
ObjectHandles registerObject(const Ice::ObjectPtr &object, const std::string &objectName, const Ice::ObjectAdapterPtr &adapterToAddTo=nullptr)
Register an object with Ice for being accessed through IceGrid.
friend class Component
Definition IceManager.h:107
void throwUserException(std::string const &message)
bool isObjectReachable(std::string objectName)
creates a proxy to the object specified with parameter objectName and tries to ping it.
IceManager(const Ice::CommunicatorPtr &communicator, std::string name="", const std::string topicSuffix="")
Set up an instance of this class with a preexisting communicator.
bool removeProxyFromCache(const std::string &name, const std::string &endpoints=std::string())
This functions removes the given proxy from the proxy cache.
Definition IceManager.h:224
ProxyType getProxy(const std::string &name, const std::string &endpoints=std::string())
Retrieves a proxy object.
Definition IceManager.h:162
void removeObject(const std::string &objectName)
Removes an object from the IceGrid.
::IceInternal::ProxyHandle<::IceProxy::IceGrid::Registry > RegistryPrx
Definition IceManager.h:75
::IceInternal::ProxyHandle<::IceProxy::IceStorm::Topic > TopicPrx
Definition IceManager.h:70
::IceInternal::ProxyHandle<::IceProxy::IceStorm::TopicManager > TopicManagerPrx
Definition IceManager.h:69
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
::IceInternal::Handle<::Ice::ObjectAdapter > ObjectAdapterPtr
Definition IceManager.h:52
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::pair< Ice::ObjectPrx, Ice::ObjectAdapterPtr > ObjectHandles
Object handles pair which contains the object proxy and its adapter.
Definition IceManager.h:97
IceUtil::Handle< IceGridAdmin > IceGridAdminPtr
Definition ArmarXFwd.h:48
std::string GetTypeString(const std::type_info &tinf, bool withoutNamespaceSpecifier=false)
IceUtil::Handle< IceManager > IceManagerPtr
IceManager smart pointer.
Definition ArmarXFwd.h:39
std::map< std::string, ManagedIceObjectDependencyPtr > DependencyList
Map of dependency names and dependecies.