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>
40#pragma GCC diagnostic pop
41
42#include <mutex>
43
44#if defined(BOOST_WINDOWS_API)
45using pipe_end = boost::asio::windows::stream_handle;
46#elif defined(BOOST_POSIX_API)
47using pipe_end = boost::asio::posix::stream_descriptor;
48#endif
49
50
51namespace armarx
52{
53 /**
54 * @class ExternalApplicationManagerPropertyDefinitions
55 * @brief
56 */
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
Defines a child process class.
Default component property definition container.
Definition Component.h:70
Baseclass for all ArmarX ManagedIceObjects requiring properties.
Definition Component.h:94
Executes a given application and keeps track if it is still running.
void terminateApplication(const Ice::Current &) override
virtual void addApplicationArguments(Ice::StringSeq &args)
std::string getPathToApplication(const Ice::Current &) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
bool isApplicationRunning(const Ice::Current &) override
virtual std::string getDefaultName() const override
void restartApplication(const Ice::Current &) override
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
IceUtil::Handle< RunningTask< T > > pointer_type
Shared pointer type for convenience.
This file offers overloads of toIce() and fromIce() functions for STL container types.
void read(auto &eigen, auto *table)
IceInternal::Handle< ExternalApplicationManagerStarter > ExternalApplicationManagerStarterPtr
IceInternal::Handle< ExternalApplicationManagerDependency > ExternalApplicationManagerDependencyPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
MessageTypeT
Definition LogSender.h:46
Convenience header which includes all public Boost.Process header files.