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 
43 using namespace std;
44 using namespace IceGrid;
45 
46 namespace 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
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
IceStorm::Parser::parse
int parse(FILE *, bool)
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
IceUtil
Definition: Instance.h:21
IceInternal::Handle<::Ice::Communicator >
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
armarx::interval
Interval< T > interval(T lo, T hi)
Definition: OccupancyGrid.h:33
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
IceGridAdmin.h
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::statechartmodel::eActivated
@ eActivated
Definition: SignalType.h:38
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::IceGridAdminPtr
IceUtil::Handle< IceGridAdmin > IceGridAdminPtr
Definition: ArmarXFwd.h:48
IceStorm::parser
Parser * parser
Definition: Parser.cpp:34
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
std
Definition: Application.h:66
LogSender.h
IceInternal::ProxyHandle
Definition: ObjectPoseClientWidget.h:45
armarx::statechartmodel::eDeactivated
@ eDeactivated
Definition: SignalType.h:39
armarx::aron::type::ObjectPtr
std::shared_ptr< Object > ObjectPtr
Definition: Object.h:36
IceGrid
Definition: IceManager.cpp:51
Logging.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27