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