ExternalApplicationManager.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package ArmarXCore::ArmarXObjects::ExternalApplicationManager
17  * @author Stefan Reither ( stef dot reither at web dot de )
18  * @date 2016
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #pragma once
24 
25 
30 #include <ArmarXCore/interface/components/ExternalApplicationManagerInterface.h>
31 
32 
33 #pragma GCC diagnostic push
34 #pragma GCC diagnostic ignored "-Wunused-result"
35 #include <boost/asio.hpp>
36 #include <boost/iostreams/device/file_descriptor.hpp>
37 #include <boost/iostreams/stream.hpp>
38 #include <boost/process.hpp>
39 #include <boost/process/child.hpp>
40 #pragma GCC diagnostic pop
41 
42 #include <mutex>
43 
44 #if defined(BOOST_WINDOWS_API)
45 using pipe_end = boost::asio::windows::stream_handle;
46 #elif defined(BOOST_POSIX_API)
47 using pipe_end = boost::asio::posix::stream_descriptor;
48 #endif
49 
50 
51 namespace armarx
52 {
53  /**
54  * @class ExternalApplicationManagerPropertyDefinitions
55  * @brief
56  */
59  {
60  public:
62  };
63 
64  /**
65  * @defgroup Component-ExternalApplicationManager ExternalApplicationManager
66  * @ingroup ArmarXCore-Components
67  * The ExternalApplicationManager can run any executale file. It can be configured to restart the given application and/or to disconnect itself if said application crashes.
68  * Applications within an ArmarX-Project can be started by setting its package and its name in the config file.
69  * In case of applications outside of ArmarX the whole path or its name if its directory is part of the PATH variable is required.\n
70  *
71  * Furthermore it provides functionalities over Ice to stop and restart the executed application.
72  *
73  * @class ExternalApplicationManager
74  * @ingroup Component-ExternalApplicationManager
75  * @brief Executes a given application and keeps track if it is still running. Provides methods for stopping and restarting said application.
76  *
77  *
78  */
80  virtual public armarx::Component,
81  virtual public armarx::ExternalApplicationManagerInterface
82  {
83  public:
84  /// @see armarx::ManagedIceObject::getDefaultName()
85  virtual std::string
86  getDefaultName() const override
87  {
88  return "ExternalApplicationManager";
89  }
90 
91  // ExternalApplicationManagerInterface
92 
93  void restartApplication(const Ice::Current&) override;
94  void terminateApplication(const Ice::Current&) override;
95  std::string getPathToApplication(const Ice::Current&) override;
96  bool isApplicationRunning(const Ice::Current&) override;
97 
98 
99  protected:
100  /// @see PropertyUser::createPropertyDefinitions()
102 
103  /// @see armarx::ManagedIceObject::onInitComponent()
104  void onInitComponent() override;
105  /// @see armarx::ManagedIceObject::onConnectComponent()
106  void onConnectComponent() override;
107  /// @see armarx::ManagedIceObject::onDisconnectComponent()
108  void onDisconnectComponent() override;
109  /// @see armarx::ManagedIceObject::onExitComponent()
110  void onExitComponent() override;
111 
112 
113  void addDependencyObject();
114  void addStarterObject();
115 
116  virtual std::string deriveWorkingDir() const;
117  virtual std::string deriveApplicationPath() const;
118  virtual void addApplicationArguments(Ice::StringSeq& args);
119 
120 
121  private:
122  struct StreamMetaData
123  {
124  StreamMetaData();
125  StreamMetaData(const StreamMetaData& data);
126 
127  MessageTypeT level;
128  boost::asio::io_service io_service;
129  boost::process::pipe pipe;
130  pipe_end pend;
131  boost::asio::streambuf input_buffer;
132  boost::iostreams::file_descriptor_sink sink;
133  std::function<void(const boost::system::error_code& error, std::size_t size)> read;
134  };
135  using StreamMetaDataPtr = std::shared_ptr<struct StreamMetaData>;
136 
137 
138  private:
139  void updateLogSenderComponentName();
140 
141  void startApplication();
142  void stopApplication();
143  void waitForApplication();
144 
145  void cleanUp();
146 
147  bool waitForProcessToFinish(int pid, int timeoutMS);
148 
149  void setupStream(StreamMetaData& meta);
150 
151 
152  private:
153  /// Either name of application or relative or absolute path
154  std::string application;
155  Ice::StringSeq args;
156  Ice::StringSeq envVars;
157  bool restartWhenCrash;
158  bool disconnectWhenCrash;
159  std::string startUpKeyword;
160  std::string workingDir;
161  bool redirectToArmarXLog;
162 
163  std::unique_ptr<boost::process::child> childProcess;
164 
165  bool isAppRunning;
166  bool appStoppedOnPurpose;
167 
169 
170  boost::iostreams::stream<boost::iostreams::file_descriptor_source> out_stream;
171  StreamMetaDataPtr outMetaData;
172 
173  boost::iostreams::stream<boost::iostreams::file_descriptor_source> err_stream;
174  StreamMetaDataPtr errMetaData;
175 
176  boost::iostreams::file_descriptor_source stdout_source;
177  boost::iostreams::file_descriptor_source stderr_source;
178 
181  std::string starterUUID, depObjUUID;
182 
185  };
186 } // namespace armarx
armarx::ExternalApplicationManager::deriveApplicationPath
virtual std::string deriveApplicationPath() const
Definition: ExternalApplicationManager.cpp:282
armarx::MessageTypeT
MessageTypeT
Definition: LogSender.h:45
process.hpp
armarx::ExternalApplicationManager::onConnectComponent
void onConnectComponent() override
Definition: ExternalApplicationManager.cpp:200
armarx::PropertyDefinitionContainer::prefix
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
Definition: PropertyDefinitionContainer.h:333
armarx::ExternalApplicationManagerStarter
Definition: ExternalApplicationManagerStarter.h:32
RunningTask.h
armarx::ExternalApplicationManagerPropertyDefinitions
Definition: ExternalApplicationManager.h:57
armarx::ExternalApplicationManager::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: ExternalApplicationManager.cpp:219
armarx::ExternalApplicationManager::getDefaultName
virtual std::string getDefaultName() const override
Definition: ExternalApplicationManager.h:86
armarx::ExternalApplicationManager::addStarterObject
void addStarterObject()
Definition: ExternalApplicationManager.cpp:409
armarx::ExternalApplicationManager::onInitComponent
void onInitComponent() override
Definition: ExternalApplicationManager.cpp:153
armarx::ExternalApplicationManager::addApplicationArguments
virtual void addApplicationArguments(Ice::StringSeq &args)
Definition: ExternalApplicationManager.cpp:121
armarx::ExternalApplicationManager::terminateApplication
void terminateApplication(const Ice::Current &) override
Definition: ExternalApplicationManager.cpp:351
armarx::ExternalApplicationManager::deriveWorkingDir
virtual std::string deriveWorkingDir() const
Definition: ExternalApplicationManager.cpp:245
armarx::ExternalApplicationManagerPropertyDefinitions::ExternalApplicationManagerPropertyDefinitions
ExternalApplicationManagerPropertyDefinitions(std::string prefix)
Definition: ExternalApplicationManager.cpp:49
armarx::ExternalApplicationManagerDependency
Definition: ExternalApplicationManagerDependency.h:33
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
child.hpp
armarx::read
void read(auto &eigen, auto *table)
Definition: FTSensorCalibrationGuiWidgetController.cpp:462
armarx::ExternalApplicationManagerDependencyPtr
IceInternal::Handle< ExternalApplicationManagerDependency > ExternalApplicationManagerDependencyPtr
Definition: ExternalApplicationManagerDependency.h:52
armarx::ExternalApplicationManager::addDependencyObject
void addDependencyObject()
Definition: ExternalApplicationManager.cpp:399
armarx::ExternalApplicationManagerStarterPtr
IceInternal::Handle< ExternalApplicationManagerStarter > ExternalApplicationManagerStarterPtr
Definition: ExternalApplicationManagerStarter.h:57
ExternalApplicationManagerDependency.h
Component.h
armarx::Component
Baseclass for all ArmarX ManagedIceObjects requiring properties.
Definition: Component.h:95
armarx::ExternalApplicationManager::onDisconnectComponent
void onDisconnectComponent() override
Definition: ExternalApplicationManager.cpp:207
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:70
armarx::ExternalApplicationManager::getPathToApplication
std::string getPathToApplication(const Ice::Current &) override
Definition: ExternalApplicationManager.cpp:357
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::ExternalApplicationManager::onExitComponent
void onExitComponent() override
Definition: ExternalApplicationManager.cpp:213
armarx::RunningTask::pointer_type
IceUtil::Handle< RunningTask< T > > pointer_type
Shared pointer type for convenience.
Definition: RunningTask.h:178
armarx::ExternalApplicationManager
Executes a given application and keeps track if it is still running. Provides methods for stopping an...
Definition: ExternalApplicationManager.h:79
armarx::ExternalApplicationManager::isApplicationRunning
bool isApplicationRunning(const Ice::Current &) override
Definition: ExternalApplicationManager.cpp:363
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
ExternalApplicationManagerStarter.h
armarx::ExternalApplicationManager::restartApplication
void restartApplication(const Ice::Current &) override
Definition: ExternalApplicationManager.cpp:344