IceGridAdmin.cpp
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 Nikolaus Vahrenkamp (vahrenkamp at kit dot edu)
20* @date 2011
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24
25#include "IceGridAdmin.h"
26
27#include <exception> // for exception
28#include <iostream> // for operator<<, endl, etc
29
30#include <Ice/Communicator.h> // for Communicator, etc
31#include <Ice/Exception.h> // for Exception
32#include <Ice/Initialize.h> //for string to identity
33#include <Ice/LocalException.h> // for ObjectNotExistException
34#include <Ice/ObjectAdapter.h> // for ObjectAdapterPtr, etc
35#include <Ice/ProxyHandle.h> // for ProxyHandle
36#include <IceGrid/Descriptor.h> // for ApplicationDescriptor
37#include <IceGrid/Exception.h>
38#include <IceGrid/FileParser.h> // for FileParserPrx, FileParser, etc
39
40#include "ArmarXCore/core/logging/LogSender.h" // for LogSender
41#include "ArmarXCore/core/logging/Logging.h" // for ARMARX_DEBUG, etc
42
43using namespace std;
44using namespace IceGrid;
45
46namespace armarx
47{
48 IceGridAdmin::IceGridAdmin(Ice::CommunicatorPtr c, std::string name) :
49 communicator(c),
50 name(name),
51 interval(IceUtil::Time::milliSeconds(500)) // call keep alive message with 2 fps
52 {
53 }
54
55 void
56 IceGridAdmin::init()
57 {
58 setTag("IceGridAdmin");
59 std::string username = "user";
60 std::string password = "password";
61
62 if (!communicator)
63 {
64 throw Ice::ObjectNotExistException(
65 "Ice::Communicator needed to create IceGridAdmin, NULL not allowed here", 0);
66 }
67
68 // create the IceGrid admin session
69 try
70 {
71 adminSessionProxy = registry()->createAdminSession(username, password);
72 }
73 catch (const IceGrid::PermissionDeniedException& e)
74 {
75 ARMARX_ERROR << "Permission denied:\n" << e.reason;
76 throw e;
77 }
78
79 // register adapter
80 std::string obsName = std::string("IceGridAdminSession_") + name;
81 Ice::ObjectPrx oPrx;
82
83 try
84 {
85 oPrx = registerObjectWithNewAdapter(this, obsName, iceGridAdminAdapter);
86 }
87 catch (const std::exception& e)
88 {
89 ARMARX_ERROR << "Register Adapter Exception: " << e.what() << "\n"
90 << "This might be happening because the property Ice.Default.Host is "
91 "wrongly set in the config (probably ~/.armarx/default.cfg)";
92 throw e;
93 }
94
95 iceGridAdminProxy = IceGrid::NodeObserverPrx::checkedCast(oPrx);
96
97 // register observer
98 setObservers();
99
100 // start timer
101 timer = new IceUtil::Timer();
102 timer->scheduleRepeated(this, interval);
103 }
104
106 IceGridAdmin::Create(Ice::CommunicatorPtr c, string name)
107 {
108 IceGridAdminPtr result = new IceGridAdmin(c, name);
109 result->init();
110 return result;
111 }
112
113 IceGridAdmin::~IceGridAdmin()
114 {
115 ARMARX_DEBUG << "*** DESTROYING IceGridAdmin <" << name << ":" << this << "> ***";
116
117 if (timer)
118 {
119 timer->destroy();
120 }
121 }
122
124 IceGridAdmin::registry()
125 {
126 if (!registryProxy)
127 {
128 Ice::ObjectPrx obj = communicator->stringToProxy("IceGrid/Registry");
129 registryProxy = IceGrid::RegistryPrx::checkedCast(obj);
130 }
131
132 return registryProxy;
133 }
134
135 IceGrid::AdminSessionPrx
136 IceGridAdmin::adminSession()
137 {
138 return adminSessionProxy;
139 }
140
141 void
142 IceGridAdmin::setObservers()
143 {
144 try
145 {
146 if (adminSession())
147 {
148 adminSession()->setObservers(nullptr, nullptr, nullptr, nullptr, nullptr);
149 adminSession()->setObservers(
150 nullptr, iceGridAdminProxy, nullptr, nullptr, this->objObserverPrx);
151 }
152 }
153 catch (const IceGrid::ObserverAlreadyRegisteredException& e)
154 {
155 ARMARX_INFO << " IceGrid observer with name " << e.id.name
156 << " already installed. State changed messages will only processed on a "
157 "polling basis, which just means a small delay.\n"
158 << "ObserverAlreadyRegisteredException:\n"
159 << e.what();
160 }
161 }
162
163 void
164 IceGridAdmin::setObjectObserver(IceGrid::ObjectObserverPrx objObserverPrx)
165 {
166 this->objObserverPrx = objObserverPrx;
167 setObservers();
168 }
169
170 void
171 IceGridAdmin::removeObservers()
172 {
173 IceGrid::NodeObserverPrx adminPrx = iceGridAdminProxy;
174 iceGridAdminProxy = nullptr;
175 IceGrid::ObjectObserverPrx objPrx = objObserverPrx;
176 objObserverPrx = nullptr;
177 setObservers();
178
179 try
180 {
181 if (objPrx)
182 {
183 getAdmin()->removeObject(objPrx->ice_getIdentity());
184 }
185
186 if (adminPrx)
187 {
188 getAdmin()->removeObject(adminPrx->ice_getIdentity());
189 iceGridAdminAdapter->destroy();
190 iceGridAdminAdapter = nullptr;
191 }
192 }
193 catch (IceGrid::ObjectNotRegisteredException& e)
194 {
195 }
196 }
197
198 IceGrid::AdminPrx
199 IceGridAdmin::getAdmin()
200 {
201 return adminSessionProxy->getAdmin();
202 }
203
204 void
205 IceGridAdmin::addApplication(const std::string& xmlPath)
206 {
207 IceGrid::FileParserPrx parser;
208 parser = IceGrid::FileParserPrx::checkedCast(communicator->stringToProxy("FileParser"));
209 IceGrid::ApplicationDescriptor descriptor = parser->parse(xmlPath, getAdmin());
210 getAdmin()->addApplication(descriptor);
211 }
212
213 void
214 IceGridAdmin::runTimerTask()
215 {
216 if (!communicator)
217 {
218 std::cout << "Communicator NULL" << std::endl;
219 return;
220 }
221
222 try
223 {
224
225 if (communicator && communicator->isShutdown())
226 {
227 // ARMARX_INFO << "*** COMMUNICATOR SHUTDOWN" << std::endl;
228 return;
229 }
230
231 if (adminSessionProxy)
232 {
233 adminSessionProxy->keepAlive();
234 }
235 else
236 {
237 ARMARX_ERROR << "!!noAdminSessionPrx!!";
238 }
239 }
240 catch (Ice::ObjectNotExistException& e)
241 {
242 ARMARX_ERROR << "*** Caught object not exist exception: " << e.what() << endl;
243
244 if (timer)
245 {
246 timer->cancel(this);
247 }
248 }
249 catch (Ice::Exception& e)
250 {
251 ARMARX_ERROR << "*** Caught exception: " << e.ice_id() << ":\n"
252 << e.what() << "\n"
253 << e.ice_stackTrace() << endl;
254
255 if (timer)
256 {
257 timer->cancel(this);
258 }
259 }
260
261 catch (std::exception& e)
262 {
263 ARMARX_ERROR << "*** Caught exception: " << e.what() << endl;
264 }
265 catch (...)
266 {
267 ARMARX_ERROR << "*** Caught unknown exception in IceGridAdmin " << endl;
268 }
269 }
270
271 void
272 IceGridAdmin::stop()
273 {
274 timer->cancel(this);
275 timer->destroy();
276 }
277
278 void
279 IceGridAdmin::cleanUpDeadObjects()
280 {
281 IceGrid::AdminPrx admin = getAdmin();
282 IceGrid::ObjectInfoSeq objects = admin->getAllObjectInfos("*");
283
284
285 for (IceGrid::ObjectInfo info : objects)
286 {
287 auto current = info.proxy;
288 try
289 {
290 current->ice_ping();
291 }
292 catch (...)
293 {
294 admin->removeObject(current->ice_getIdentity());
295 }
296 }
297 }
298
299 Ice::ObjectPrx
300 IceGridAdmin::registerObjectWithNewAdapter(Ice::ObjectPtr object,
301 const std::string& objectName,
302 Ice::ObjectAdapterPtr& objectAdapter)
303 {
304 ARMARX_VERBOSE << "Registering object with name '" << objectName
305 << "' with new adapter in Ice";
306 objectAdapter = communicator->createObjectAdapterWithEndpoints(objectName, "tcp");
307 Ice::Identity id = Ice::stringToIdentity(objectName);
308
309 objectAdapter->add(object, id);
310 objectAdapter->activate();
311
312 IceGrid::AdminPrx admin = getAdmin();
313
314 Ice::ObjectPrx proxy = objectAdapter->createProxy(id);
315
316 try
317 {
318 admin->addObjectWithType(proxy, proxy->ice_id());
319 }
320 catch (const IceGrid::ObjectExistsException&)
321 {
322 admin->updateObject(proxy);
323 }
324
325 return proxy;
326 }
327
328 IceGridAdmin::ComponentState
329 IceGridAdmin::getComponentState(std::string id)
330 {
331 Ice::ObjectPrx proxy = communicator->stringToProxy(id);
332
333 if (!proxy)
334 {
335 cerr << "No proxy for id " << id << endl;
336 return eUnknown;
337 }
338
339 try
340 {
341 proxy->ice_twoway()->ice_ping();
342 }
343 catch (const Ice::Exception&)
344 {
345 //cerr << "object " << id << " not reachable" << endl;
346 return eDeactivated;
347 }
348
349 //cerr << "object " << id << " is reachable" << endl;
350 return eActivated;
351 }
352
353 void
354 IceGridAdmin::nodeInit(const IceGrid::NodeDynamicInfoSeq& nodes, const Ice::Current& c)
355 {
356 ARMARX_DEBUG << __PRETTY_FUNCTION__ << endl;
357
358 for (unsigned int i = 0; i < nodes.size(); i++)
359 {
360 ARMARX_DEBUG << "Node " << i << ": " << nodes[i].info.name << endl;
361 }
362 }
363
364 void
365 IceGridAdmin::nodeUp(const IceGrid::NodeDynamicInfo& node, const Ice::Current& c)
366 {
367 ARMARX_DEBUG << __PRETTY_FUNCTION__ << endl;
368 ARMARX_DEBUG << "Node:" << node.info.name << endl;
369 }
370
371 void
372 IceGridAdmin::nodeDown(const std::string& name, const Ice::Current& c)
373 {
374 ARMARX_DEBUG << __PRETTY_FUNCTION__ << endl;
375 ARMARX_DEBUG << "Node:" << name << endl;
376 }
377
378 void
379 IceGridAdmin::notifyComponentChanged(ComponentState state, std::string id)
380 {
381 }
382
383 void
384 IceGridAdmin::reportRemoteComponentStateChange(const IceGrid::ServerDynamicInfo& updatedInfo)
385 {
386 std::unique_lock lock(mutexComponentStateUpdate);
387
388 std::string idServer = updatedInfo.id;
389 std::string serverString = "Server";
390
391 // check if we have to remove the "Server" string that is added to the ID
392 if (idServer.compare(idServer.size() - 6, 6, serverString) == 0)
393 {
394 idServer = idServer.substr(0, idServer.size() - 6);
395 }
396
397 if (remoteComponentsState.find(idServer) == remoteComponentsState.end())
398 {
399 // no requests for this id have been queried
400 // cout << "** no observer request for " << idServer << endl;
401 return;
402 }
403
404 //cout << "remoteComponentsState[idServer]:" << remoteComponentsState[idServer] << endl;
405 switch (updatedInfo.state)
406 {
407 case IceGrid::Inactive:
408 case IceGrid::Activating:
409 case IceGrid::ActivationTimedOut:
410 case IceGrid::Deactivating:
411 case IceGrid::Destroying:
412 case IceGrid::Destroyed:
413
414 if (remoteComponentsState[idServer] == eActivated)
415 {
416 //cout << idServer << ": state == eActivated->notify" << endl;
417 notifyComponentChanged(eDeactivated, idServer);
418 }
419
420 remoteComponentsState[idServer] = eDeactivated;
421 break;
422
423 case IceGrid::Active:
424
425 if (remoteComponentsState[idServer] != eActivated)
426 {
427 //cout << idServer << ": state != eActivated->notify" << endl;
428 notifyComponentChanged(eActivated, idServer);
429 }
430
431 remoteComponentsState[idServer] = eActivated;
432 break;
433
434 default:
435 cerr << __PRETTY_FUNCTION__ << "Unknown state" << endl;
436
437 if (remoteComponentsState[idServer] == eActivated)
438 {
439 notifyComponentChanged(eDeactivated, idServer);
440 }
441
442 remoteComponentsState[idServer] = eUnknown;
443 break;
444 }
445 }
446
447 void
448 IceGridAdmin::printServerInfo(const IceGrid::ServerDynamicInfo& updatedInfo)
449 {
450 cout << "Server:" << updatedInfo.id << endl;
451 cout << "** enabled:";
452
453 if (updatedInfo.enabled)
454 {
455 cout << "true" << endl;
456 }
457 else
458 {
459 cout << "false" << endl;
460 }
461
462 cout << "** Server state:";
463
464 switch (updatedInfo.state)
465 {
466 case IceGrid::Inactive:
467 cout << "Inactive" << endl;
468 break;
469
470 case IceGrid::Activating:
471 cout << "Activating" << endl;
472 break;
473
474 case IceGrid::ActivationTimedOut:
475 cout << "ActivationTimedOut" << endl;
476 break;
477
478 case IceGrid::Active:
479 cout << "Active" << endl;
480 break;
481
482 case IceGrid::Deactivating:
483 cout << "Deactivating" << endl;
484 break;
485
486 case IceGrid::Destroying:
487 cout << "Destroying" << endl;
488 break;
489
490 case IceGrid::Destroyed:
491 cout << "Destroyed" << endl;
492 break;
493
494 default:
495 cout << "unknown" << endl;
496 }
497 }
498
499 void
500 IceGridAdmin::updateServer(const std::string& node,
501 IceGrid::ServerDynamicInfo updatedInfo,
502 const Ice::Current& c)
503 {
504 //cout << __PRETTY_FUNCTION__ << "2" <<endl;
505 //cout << "Node:" << node << endl;
506 //printServerInfo(updatedInfo);
507 reportRemoteComponentStateChange(updatedInfo);
508 }
509
510 void
511 IceGridAdmin::updateAdapter(const std::string& node,
512 IceGrid::AdapterDynamicInfo updatedInfo,
513 const Ice::Current& c)
514 {
515 // cout << __PRETTY_FUNCTION__ << endl;
516 }
517
518 void
519 IceGridAdmin::updateServer(const ::std::string& node,
520 const ::IceGrid::ServerDynamicInfo& updateServer,
521 const ::Ice::Current& c)
522 {
523 //cout << __PRETTY_FUNCTION__ << "1" <<endl;
524 //printServerInfo(updateServer);
525 reportRemoteComponentStateChange(updateServer);
526 }
527
528 void
529 IceGridAdmin::updateAdapter(const ::std::string& node,
530 const ::IceGrid::AdapterDynamicInfo& updatedInfo,
531 const ::Ice::Current& c)
532 {
533 // cout << __PRETTY_FUNCTION__ << endl;
534 }
535} // namespace armarx
constexpr T c
int parse(FILE *, bool)
Definition Parser.cpp:585
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
::IceInternal::ProxyHandle<::IceProxy::IceGrid::Registry > RegistryPrx
Definition IceManager.h:75
Parser * parser
Definition Parser.cpp:34
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
::IceInternal::Handle<::Ice::ObjectAdapter > ObjectAdapterPtr
Definition IceManager.h:52
armarx::core::time::DateTime Time
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< IceGridAdmin > IceGridAdminPtr
Definition ArmarXFwd.h:48
Interval< T > interval(T lo, T hi)