Application.h 10.7 KB
Newer Older
legoc's avatar
legoc committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright 2015 Institut Laue-Langevin
 *
 * Licensed under the EUPL, Version 1.1 only (the "License");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://joinup.ec.europa.eu/software/page/eupl
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the Licence is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Licence for the specific language governing permissions and
 * limitations under the Licence.
 */

#ifndef CAMEO_APPLICATION_H_
#define CAMEO_APPLICATION_H_

20
#include "InvalidArgumentException.h"
21
#include "UnmanagedApplicationException.h"
22
#include "SocketException.h"
23
#include "ConnectionTimeout.h"
legoc's avatar
legoc committed
24
25
#include "UndefinedApplicationException.h"
#include "UndefinedKeyException.h"
26
#include "Response.h"
27
#include "Serializer.h"
legoc's avatar
legoc committed
28
#include "Context.h"
legoc's avatar
legoc committed
29
#include "TimeCondition.h"
30
#include "EventListener.h"
31
#include "JSON.h"
32
#include "KeyValue.h"
33
34
35
36
37
38
#include "Strings.h"
#include <functional>
#include <vector>
#include <set>
#include <memory>
#include <optional>
legoc's avatar
legoc committed
39
40
41

namespace cameo {

42
43
44
45
/**
 * Option output stream.
 */
const int OUTPUTSTREAM = 1;
legoc's avatar
legoc committed
46
47
48

class Server;
class EventStreamSocket;
legoc's avatar
legoc committed
49
class OutputStreamSocket;
legoc's avatar
legoc committed
50
51
52
53
class WaitingImpl;
class SocketWaitingImpl;
class GenericWaitingImpl;
class WaitingImplSet;
54
class HandlerImpl;
55
class RequestSocketImpl;
56
57

namespace coms {
legoc's avatar
legoc committed
58
59
60
61
62
63

// forward declarations
class Publisher;
class Subscriber;
class Responder;
class Requester;
64
65
66
67
68
69
70
71
72
73
class PublisherImpl;
class SubscriberImpl;
class RequestImpl;
class ResponderImpl;
class RequesterImpl;

}

namespace application {

legoc's avatar
legoc committed
74
75
76
77
78
class Instance;
class Waiting;

typedef int32_t State;

legoc's avatar
legoc committed
79
80
#undef ERROR

81
82
83
84
85
const State UNKNOWN          = 0;
const State STARTING         = 1;
const State RUNNING          = 2;
const State STOPPING         = 4;
const State KILLING          = 8;
legoc's avatar
legoc committed
86
const State PROCESSING_ERROR = 16;
87
88
89
90
91
92
93
94
95
96
97
const State FAILURE          = 32;
const State SUCCESS          = 64;
const State STOPPED          = 128;
const State KILLED           = 256;

/** \class This
 * \brief class managing the current CAMEO application.
 *
 * \details The application has to be launched by CAMEO command line or another CAMEO app
 * \todo why this does not inherit from the Instance class?
 */
legoc's avatar
legoc committed
98
class This : private EventListener {
legoc's avatar
legoc committed
99

100
101
102
103
104
105
106
	friend class cameo::coms::Publisher;
	friend class cameo::coms::Responder;
	friend class cameo::coms::Requester;
	friend class cameo::coms::PublisherImpl;
	friend class cameo::coms::RequestImpl;
	friend class cameo::coms::ResponderImpl;
	friend class cameo::coms::RequesterImpl;
legoc's avatar
legoc committed
107
108
109
110
111
	friend class cameo::SocketWaitingImpl;
	friend class cameo::GenericWaitingImpl;
	friend class cameo::Server;
	friend std::ostream& operator<<(std::ostream&, const cameo::application::This&);

112
	typedef std::function<void()> StopFunctionType;
legoc's avatar
legoc committed
113
114

public:
115
116
117
118
119
120
121
122
	/**
	 * Class defining the Communication Operations Manager (COM).
	 */
	class Com {

		friend class This;

	public:
legoc's avatar
legoc committed
123
124
		Context* getContext() const;

125
126
127
128
		void storeKeyValue(const std::string& key, const std::string& value) const;
		std::string getKeyValue(const std::string& key) const;
		void removeKey(const std::string& key) const;

legoc's avatar
legoc committed
129
130
131
132
		int requestPort() const;
		void setPortUnavailable(int port) const;
		void releasePort(int port) const;

legoc's avatar
legoc committed
133
		json::Object requestJSON(const std::string& request, int overrideTimeout = -1) const;
legoc's avatar
legoc committed
134
135
136
137

		std::unique_ptr<RequestSocketImpl> createRequestSocket(const std::string& endpoint) const;
		std::unique_ptr<RequestSocketImpl> createRequestSocket(const std::string& endpoint, int timeout) const;

138
139
		void removePort(const std::string& name) const;

140
	private:
141
		Com(Server* server, int applicationId);
142

143
		Server* m_server;
144
145
146
		int m_applicationId;
	};

147
148
149
	This();
	~This();

150
	static void init(int argc, char* argv[]);
151
	static void init(const std::string& name, const std::string& endpoint);
152
153

	/**
154
155
	 * The terminate call is not necessary unless the static instance of This is not destroyed
	 * automatically.
156
	 */
legoc's avatar
legoc committed
157
158
	static void terminate();

159
160
161
	/// \brief returns the name of the CAMEO application corresponding to this instance
	static const std::string& getName(); 
	static int getId(); ///< returns the ID number of the instance
legoc's avatar
legoc committed
162
	static void setTimeout(int value);
legoc's avatar
legoc committed
163
	static int getTimeout();
164
	static const Endpoint& getEndpoint(); ///< returns the TCP address of this instance
legoc's avatar
legoc committed
165
	static Server& getServer();
166
	static const Com& getCom();
legoc's avatar
legoc committed
167
168
169
170
171
172
173
174

	/**
	 * throws StarterServerException.
	 */
	static Server& getStarterServer();
	static bool isAvailable(int timeout = 10000);
	static bool isStopping();

175
	/**
176
177
	 * Sets the stop handler with stopping time that overrides the one that may be defined in the
	 * configuration of the server.
178
	 */
179
	template <typename Type>
180
181
	static void handleStop(Type function, int stoppingTime = -1) {
		m_instance.handleStopImpl(function, stoppingTime);
legoc's avatar
legoc committed
182
183
184
185
	}

	static void cancelWaitings();

186
	static bool setRunning(); ///< sets the current instance in RUNNING state
legoc's avatar
legoc committed
187
188
189
190
191
192
193
194
195
196

	/**
	 * Sets the result.
	 */
	static void setBinaryResult(const std::string& data);
	static void setResult(const std::string& data);

	/**
	 * Connects to the starter application, i.e. the application which started this application.
	 */
legoc's avatar
legoc committed
197
	static std::unique_ptr<Instance> connectToStarter();
legoc's avatar
legoc committed
198
199

private:
200
	void initApplication(int argc, char* argv[]);
201
	void initApplication(const std::string& name, const std::string& endpoint);
legoc's avatar
legoc committed
202
203
	void initApplication();

legoc's avatar
legoc committed
204
205
	static State parseState(const std::string& value);
	State getState(int id) const;
legoc's avatar
legoc committed
206
207
208
209

	int initUnmanagedApplication();
	void terminateUnmanagedApplication();

legoc's avatar
legoc committed
210
	State waitForStop();
211
212

	void stoppingFunction(StopFunctionType stop);
213
	void handleStopImpl(StopFunctionType function, int stoppingTime);
legoc's avatar
legoc committed
214
215
216

	std::string m_name;
	int m_id;
legoc's avatar
legoc committed
217
	bool m_managed;
legoc's avatar
legoc committed
218

legoc's avatar
legoc committed
219
	Endpoint m_serverEndpoint;
legoc's avatar
legoc committed
220
	Endpoint m_starterEndpoint;
legoc's avatar
legoc committed
221
222
223
	std::string m_starterName;
	int m_starterId;

legoc's avatar
legoc committed
224
225
	std::unique_ptr<Server> m_server;
	std::unique_ptr<Server> m_starterServer;
226
	std::unique_ptr<Com> m_com;
legoc's avatar
legoc committed
227

legoc's avatar
legoc committed
228
	std::unique_ptr<WaitingImplSet> m_waitingSet;
229
	std::unique_ptr<HandlerImpl> m_stopHandler;
legoc's avatar
legoc committed
230

legoc's avatar
legoc committed
231
232
	bool m_inited;

233
	static This m_instance;
legoc's avatar
legoc committed
234
235
236
237
	static const std::string RUNNING_STATE;
};


238
class Instance : private EventListener {
legoc's avatar
legoc committed
239
240

	friend class cameo::Server;
241
	friend class cameo::coms::Subscriber;
legoc's avatar
legoc committed
242
243
244
	friend std::ostream& operator<<(std::ostream&, const Instance&);

public:
245
	typedef std::function<void(State)> StateHandlerType;
legoc's avatar
legoc committed
246

247
248
249
250
251
252
	class Com {

		friend class Instance;

	public:
		std::string getKeyValue(const std::string& key) const;
legoc's avatar
legoc committed
253
		json::Object requestJSON(const std::string& request, int overrideTimeout = -1) const;
254
255

	private:
256
		Com(Server* server);
257

258
		Server* m_server;
259
260
261
		int m_applicationId;
	};

legoc's avatar
legoc committed
262
263
	~Instance();

legoc's avatar
legoc committed
264
	const std::string& getName() const;
legoc's avatar
legoc committed
265
	int getId() const;
266
267
	Endpoint getEndpoint() const;
	Endpoint getStatusEndpoint() const;
legoc's avatar
legoc committed
268
	std::string getNameId() const;
269
270
	const Com& getCom() const;

legoc's avatar
legoc committed
271
272
273
274
275
	bool hasResult() const;
	bool exists() const;
	const std::string& getErrorMessage() const;
	bool stop();
	bool kill();
legoc's avatar
legoc committed
276

277
278
279
280
	State waitFor(int states, StateHandlerType handler);
	State waitFor(int states);
	State waitFor(StateHandlerType handler);
	State waitFor();
legoc's avatar
legoc committed
281
	State waitFor(const std::string& eventName);
282
	State waitFor(KeyValue& keyValue);
legoc's avatar
legoc committed
283

284
	void cancelWaitFor(); // to unblock another instance
legoc's avatar
legoc committed
285

286
287
288
289
	/**
	 * Deprecated.
	 * TODO remove in next version.
	 */
290
291
	State now();

292
293
294
295
296
297
298
299
300
301
	/**
	 * Gets the last state.
	 */
	State getLastState();

	/**
	 * Returns the actual state and UNKNOWN if the instance does not exist anymore.
	 */
	State getActualState() const;

302
303
304
305
306
	/**
	 * Returns the past states.
	 */
	std::set<State> getPastStates() const;

307
308
309
310
311
	/**
	 * Returns the exit code.
	 */
	int getExitCode() const;

312
313
	std::optional<std::string> getBinaryResult();
	std::optional<std::string> getResult();
legoc's avatar
legoc committed
314

315
	std::unique_ptr<OutputStreamSocket> getOutputStreamSocket();
legoc's avatar
legoc committed
316

legoc's avatar
legoc committed
317
private:
318
	Instance(Server* server);
legoc's avatar
legoc committed
319
320
321

	void setId(int id);
	void setErrorMessage(const std::string& message);
legoc's avatar
legoc committed
322
	void setOutputStreamSocket(std::unique_ptr<OutputStreamSocket>& socket);
legoc's avatar
legoc committed
323
324
	void setPastStates(State pastStates);
	void setInitialState(State state);
325
	State waitFor(int states, const std::string& eventName, KeyValue& keyValue, StateHandlerType handler, bool blocking);
legoc's avatar
legoc committed
326

327
	Server* m_server;
328
	std::unique_ptr<OutputStreamSocket> m_outputStreamSocket;
legoc's avatar
legoc committed
329
330
	int m_id;
	std::string m_errorMessage;
331
332
	Com m_com;

legoc's avatar
legoc committed
333
334
335
336
337
	int m_pastStates;
	State m_initialState;
	State m_lastState;
	bool m_hasResult;
	std::string m_resultData;
338
	int m_exitCode;
339
	std::unique_ptr<WaitingImpl> m_waiting;
legoc's avatar
legoc committed
340
341
342
343
344
};

///////////////////////////////////////////////////////////////////////////
// InstanceArray

345
typedef std::vector<std::unique_ptr<Instance>> InstanceArray;
legoc's avatar
legoc committed
346
347
348
349
350
351
352
353
354
355


///////////////////////////////////////////////////////////////////////////
// Configuration

class Configuration {

	friend std::ostream& operator<<(std::ostream&, const Configuration&);

public:
356
357
	Configuration(const std::string& name, const std::string& description, bool singleInfo, bool restart,
		      int startingTime, int stoppingTime);
legoc's avatar
legoc committed
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382

	const std::string& getName() const;
	const std::string& getDescription() const;
	bool hasSingleInstance() const;
	bool canRestart() const;
	int getStartingTime() const;
	int getStoppingTime() const;

private:
	std::string m_name;
	std::string m_description;
	bool m_singleInstance;
	bool m_restart;
	int m_startingTime;
	int m_stoppingTime;
};

///////////////////////////////////////////////////////////////////////////
// Info

class Info {

	friend std::ostream& operator<<(std::ostream&, const Info&);

public:
383
384
	Info(const std::string& name, int id, int pid, State applicationState, State pastApplicationStates,
	     const std::string& args);
legoc's avatar
legoc committed
385
386
387
388
389
390

	int getId() const;
	State getState() const;
	State getPastStates() const;
	const std::string& getArgs() const;
	const std::string& getName() const;
legoc's avatar
legoc committed
391
	int getPid() const;
legoc's avatar
legoc committed
392
393
394

private:
	int m_id;
legoc's avatar
legoc committed
395
	int m_pid;
legoc's avatar
legoc committed
396
397
398
399
400
401
402
	State m_applicationState;
	State m_pastApplicationStates;
	std::string m_processState;
	std::string m_args;
	std::string m_name;
};

legoc's avatar
legoc committed
403
404
405
406
407
408
409
410
///////////////////////////////////////////////////////////////////////////
// Port

class Port {

	friend std::ostream& operator<<(std::ostream&, const Port&);

public:
legoc's avatar
legoc committed
411
	Port(int port, const std::string& status, const std::string& owner);
legoc's avatar
legoc committed
412
413
414

	int getPort() const;
	const std::string& getStatus() const;
legoc's avatar
legoc committed
415
	const std::string& getOwner() const;
legoc's avatar
legoc committed
416
417
418
419

private:
	int m_port;
	std::string m_status;
legoc's avatar
legoc committed
420
	std::string m_owner;
legoc's avatar
legoc committed
421
422
};

legoc's avatar
legoc committed
423
424
425
426
427
std::string toString(cameo::application::State applicationStates);
std::ostream& operator<<(std::ostream&, const cameo::application::This&);
std::ostream& operator<<(std::ostream&, const cameo::application::Instance&);
std::ostream& operator<<(std::ostream&, const cameo::application::Configuration&);
std::ostream& operator<<(std::ostream&, const cameo::application::Info&);
legoc's avatar
legoc committed
428
std::ostream& operator<<(std::ostream&, const cameo::application::Port&);
legoc's avatar
legoc committed
429

430
431
} // namespace application
} // namespace cameo
legoc's avatar
legoc committed
432
433

#endif