1 | /********************************************************************\
|
---|
2 |
|
---|
3 | Alarm handler of the Evidence Control System
|
---|
4 |
|
---|
5 | - Checks periodically if all required servers are up
|
---|
6 | (later it should try to start them if not)
|
---|
7 | - Listens to the 'Status' service of each server. The server state
|
---|
8 | is published as a DIM service.
|
---|
9 |
|
---|
10 | Oliver Grimm, September 2009
|
---|
11 |
|
---|
12 | \********************************************************************/
|
---|
13 |
|
---|
14 | #define SERVER_NAME "Alarm"
|
---|
15 | #include "../Evidence.h"
|
---|
16 |
|
---|
17 | //
|
---|
18 | // Data handling class
|
---|
19 | //
|
---|
20 | class AlarmHandler : public DimClient, public EvidenceServer {
|
---|
21 |
|
---|
22 | DimStampedInfo **StatusService;
|
---|
23 | void infoHandler();
|
---|
24 |
|
---|
25 | public:
|
---|
26 | AlarmHandler();
|
---|
27 | ~AlarmHandler();
|
---|
28 |
|
---|
29 | char **Server;
|
---|
30 | unsigned int NumServers;
|
---|
31 | char *StateString;
|
---|
32 | char *ServerList;
|
---|
33 | };
|
---|
34 |
|
---|
35 | // Constructor
|
---|
36 | AlarmHandler::AlarmHandler(): EvidenceServer(SERVER_NAME) {
|
---|
37 |
|
---|
38 | char *ServerNames = GetConfig(SERVER_NAME " servers");
|
---|
39 |
|
---|
40 | // Copy original list of servers to observe
|
---|
41 | ServerList = new char [strlen(ServerNames)+1];
|
---|
42 | strcpy(ServerList, ServerNames);
|
---|
43 |
|
---|
44 | // Extract DIM servers to observe
|
---|
45 | Server = new char* [strlen(ServerNames)];
|
---|
46 | NumServers = 0;
|
---|
47 | char *NextToken = strtok(ServerNames, " \t");
|
---|
48 | while (NextToken != NULL) {
|
---|
49 | Server[NumServers++] = NextToken; // Subscribe with handler
|
---|
50 | NextToken = strtok(NULL, " \t");
|
---|
51 | }
|
---|
52 |
|
---|
53 | // Subscribe with handler to 'Status' service of all servers
|
---|
54 | StatusService = new DimStampedInfo* [NumServers];
|
---|
55 |
|
---|
56 | for (int i=0; i<NumServers; i++) {
|
---|
57 | char *Buffer = new char [strlen(Server[i])+10];
|
---|
58 | strcpy(Buffer, Server[i]);
|
---|
59 | strcat(Buffer, "/Status");
|
---|
60 | StatusService[i] = new DimStampedInfo(Buffer, 0, this);
|
---|
61 | printf("Subscribed to %s\n", Buffer);
|
---|
62 | delete[] Buffer;
|
---|
63 | }
|
---|
64 |
|
---|
65 | StateString = new char [NumServers+1];
|
---|
66 | for (int i=0; i<NumServers; i++) StateString[i] = '1';
|
---|
67 | StateString[NumServers] = '\0';
|
---|
68 | }
|
---|
69 |
|
---|
70 | // Destructor
|
---|
71 | AlarmHandler::~AlarmHandler() {
|
---|
72 |
|
---|
73 | for (int i=0; i<NumServers; i++) delete StatusService[i];
|
---|
74 | delete[] StatusService;
|
---|
75 | delete[] Server;
|
---|
76 | delete[] ServerList;
|
---|
77 | }
|
---|
78 |
|
---|
79 | // Print messages of status changes to screen
|
---|
80 | void AlarmHandler::infoHandler() {
|
---|
81 |
|
---|
82 | // Ignore empty messages
|
---|
83 | if (strlen(getInfo()->getString()) == 0) return;
|
---|
84 |
|
---|
85 | // Print message
|
---|
86 | time_t RawTime = getInfo()->getTimestamp();
|
---|
87 | struct tm *TM = localtime(&RawTime);
|
---|
88 | printf("%s (%02d:%02d:%02d): %s\n", getInfo()->getName(), TM->tm_hour,
|
---|
89 | TM->tm_min, TM->tm_sec, getInfo()->getString());
|
---|
90 |
|
---|
91 | // Update status string
|
---|
92 | for (int i=0; i<NumServers; i++) {
|
---|
93 | if (strcmp(getInfo()->getName(),Server[i]) == 0) {
|
---|
94 | StateString[i] = '2';
|
---|
95 | }
|
---|
96 | }
|
---|
97 | }
|
---|
98 |
|
---|
99 |
|
---|
100 | //
|
---|
101 | // Main program
|
---|
102 | //
|
---|
103 | int main() {
|
---|
104 |
|
---|
105 | DimBrowser Browser;
|
---|
106 | char *ServerName, *Node;
|
---|
107 | bool Exists;
|
---|
108 |
|
---|
109 | // Static declaration ensures calling of destructor by exit()
|
---|
110 | static AlarmHandler Alarm;
|
---|
111 |
|
---|
112 | // Request configuration data
|
---|
113 | unsigned int Period = atoi(Alarm.GetConfig(SERVER_NAME " period"));
|
---|
114 |
|
---|
115 | // Create DIM services
|
---|
116 | static DimService ServerState(SERVER_NAME"/State", Alarm.StateString);
|
---|
117 | static DimService ServerList(SERVER_NAME"/Servers", Alarm.ServerList);
|
---|
118 |
|
---|
119 | // Check periodically if servers are up
|
---|
120 | while(!EvidenceServer::ExitRequest) {
|
---|
121 | for (int i=0; i<Alarm.NumServers; i++) {
|
---|
122 | Exists = false;
|
---|
123 | Browser.getServers();
|
---|
124 | while (Browser.getNextServer(ServerName, Node) == 1) {
|
---|
125 | if (strcmp(ServerName, Alarm.Server[i]) == 0) Exists = true;
|
---|
126 | }
|
---|
127 | if (!Exists) {
|
---|
128 | Alarm.Msg(Alarm.WARN, "Server %s unavailable", Alarm.Server[i]);
|
---|
129 | Alarm.StateString[i] = '0';
|
---|
130 | }
|
---|
131 | else if (Alarm.StateString[i] == '0') Alarm.StateString[i] = '1';
|
---|
132 | }
|
---|
133 |
|
---|
134 | ServerState.updateService(Alarm.StateString);
|
---|
135 | sleep(Period);
|
---|
136 | }
|
---|
137 | }
|
---|