blob: c263f7afb1abb09f1308d91ee4c8ce085fdfea32 [file] [log] [blame]
E. Scott Daniels6ef23e12020-07-15 08:03:22 -04001// vi: ts=4 sw=4 noet:
2/*
3==================================================================================
4 Copyright (c) 2020 Nokia
5 Copyright (c) 2020 AT&T Intellectual Property.
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18==================================================================================
19*/
20
21/*
22 Mnemonic: alarm.cpp
23 Abstract: This class provides an API to the alarm collector/reporter.
24 An object is insanced by the user xAPP allowing the xAPP
25 to send, clear, or resend the alarm as is necessary.
26
27
28 Date: 15 July 2020
29 Author: E. Scott Daniels
30*/
31
32#include <string.h>
33#include <unistd.h>
34#include <time.h>
E. Scott Daniels23d0e612020-09-17 15:46:48 -040035#include <iostream>
E. Scott Daniels6ef23e12020-07-15 08:03:22 -040036
37#include <rmr/RIC_message_types.h>
E. Scott Daniels23d0e612020-09-17 15:46:48 -040038
39#include "msg_component.hpp"
40#include "message.hpp"
41#include "alarm.hpp"
42
E. Scott Daniels6ef23e12020-07-15 08:03:22 -040043#ifndef RIC_ALARM
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -040044 // this _should_ come from the message types header, but if not ensure we have something
45 constexpr int ric_alarm_value = 110;
46 #define RIC_ALARM ric_alarm_value
E. Scott Daniels6ef23e12020-07-15 08:03:22 -040047#endif
48
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -040049extern const char* __progname; // runtime lib supplied since we don't get argv[0]
E. Scott Daniels6ef23e12020-07-15 08:03:22 -040050
51namespace xapp {
52
53
54
55// ------ private ----------------------------------------------
56
57/*
58 Suss out the alarm target from environment.
59
60 We expect two variables in the environment:
61 ALARM_MGR_SERVICE_NAME
62 ALARM_MGR_SERVICE_PORT
63
64 If name is not given, localhost is assumed. If port is not given
65 then we assume 4560 (the defacto RMR listen port).
66*/
67static std::string endpoint_addr( ) {
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -040068 const char* et; // environment token
E. Scott Daniels6ef23e12020-07-15 08:03:22 -040069 std::string addr = "localhost";
70 std::string port = "4560";
71
72 if( (et = getenv( "ALARM_MGR_SERVICE_NAME" )) != NULL ) {
73 addr = std::string( et );
74 }
75
76 if( (et = getenv( "ALARM_MGR_SERVICE_PORT" )) != NULL ) {
77 port = std::string( et );
78 }
79
80 return addr + ":" + port;
81}
82
83
84/*
85 Return the current time in milliseconds past the UNIX epoch.
86*/
87static long long now( void ) {
88 struct timespec ts;
89 long long now = 0;
90
91 clock_gettime( CLOCK_REALTIME, &ts );
92 now = (ts.tv_sec * 1000000) + (ts.tv_nsec/1000000); // convert nano to milli and bang onto seconds
93
94 return now;
95}
96
97
98/*
99 Build the alarm json message with the current data.
100 Returns the length of the payload inserted.
101*/
102int xapp::Alarm::build_alarm( int action_id, xapp::Msg_component payload, int payload_len ) {
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400103 std::string maction; // message action is a text string
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400104 int used;
105
106 if( app_id.compare( "" ) == 0 ) {
107 app_id = std::string( __progname ); // see comment for extern above
108 }
109
110 if( severity.compare( "" ) == 0 ) {
111 Set_severity( Alarm::SEV_WARN );
112 }
113
114 switch( action_id ) {
115 case Alarm::ACT_CLEAR:
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400116 maction = "CLEAR";
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400117 break;
118
119 case Alarm::ACT_CLEAR_ALL:
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400120 maction = "CLEARALL";
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400121 break;
122
123 default:
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400124 maction = "RAISE";
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400125 break;
126 }
127
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400128 used = snprintf( (char *) payload.get(), payload_len,
129 "{ "
130 "\"managedObjectId\": \"%s\", "
131 "\"applicationId\": \"%s\", "
132 "\"specificProblem\": %d, "
133 "\"perceivedSeverity\": \"%s\", "
134 "\"identifyingInfo\": \"%s\", "
135 "\"additionalInfo\": \"%s\", "
136 "\"AlarmAction\": \"%s\", "
137 "\"AlarmTime\": %lld"
138 " }",
139
140 me_id.c_str(),
141 app_id.c_str(),
142 problem_id,
143 severity.c_str(),
144 info.c_str(),
145 add_info.c_str(),
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400146 maction.c_str(),
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400147 now()
148 );
149
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400150 return used;
151}
152
153// --------------- builders/operators -------------------------------------
154
155/*
156 Create a new message wrapper for an existing RMR msg buffer.
157
158 msg is a message which was allocaed by the framework and thus has the
159 mrc reference embedded.
160*/
161xapp::Alarm::Alarm( std::shared_ptr<Message> msg ) :
162 msg( msg ),
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400163 endpoint( endpoint_addr() )
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400164{ /* empty body */ }
165
166/*
167 Parameterised constructor (avoids calling setters after creation).
168*/
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400169xapp::Alarm::Alarm( std::shared_ptr<Message> msg, int prob_id, const std::string& meid ) :
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400170 msg( msg ),
171 endpoint( endpoint_addr() ),
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400172 me_id( meid ),
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400173 problem_id( prob_id )
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400174{ /* empty body */ }
175
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400176xapp::Alarm::Alarm( std::shared_ptr<Message> msg, const std::string& meid ) :
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400177 msg( msg ),
178 endpoint( endpoint_addr() ),
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400179 me_id( meid )
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400180{ /* empty body */ }
181
182
183
184// ------------------ copy and move support ---------------------------------
185
186/*
187 Copy builder. Given a source object instance (soi), create a copy.
188 Creating a copy should be avoided as it can be SLOW!
189*/
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400190xapp::Alarm::Alarm( const Alarm& soi ) :
191 msg( soi.msg ),
192 endpoint( soi.endpoint ),
193 whid( soi.whid ),
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400194
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400195 me_id( soi.me_id ), // user stuff
196 app_id( soi.app_id ),
197 problem_id( soi.problem_id ),
198 severity( soi.severity ),
199 info( soi.info ),
200 add_info( soi.add_info )
201{ /* empty body */ }
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400202
203/*
204 Assignment operator. Simiolar to the copycat, but "this" object exists and
205 may have data that needs to be released prior to making a copy of the soi.
206*/
207Alarm& xapp::Alarm::operator=( const Alarm& soi ) {
208 if( this != &soi ) { // cannot do self assignment
209 msg = soi.msg;
210 endpoint = soi.endpoint;
211 whid = soi.whid;
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400212 me_id = soi.me_id;
213 app_id = soi.app_id;
214 problem_id = soi.problem_id;
215 severity = soi.severity;
216 info = soi.info;
217 add_info = soi.add_info;
218 }
219
220 return *this;
221}
222
223/*
224 Move builder. Given a source object instance (soi), move the information from
225 the soi ensuring that the destriction of the soi doesn't trash things from
226 under us.
227*/
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400228xapp::Alarm::Alarm( Alarm&& soi ) :
229 msg( soi.msg ), // order must match .hpp else sonar complains
230 endpoint( soi.endpoint ),
231 whid( soi.whid ),
232 me_id( soi.me_id ),
233 app_id( soi.app_id ),
234 problem_id( soi.problem_id ),
235 severity( soi.severity ),
236 info( soi.info ),
237 add_info( soi.add_info )
238{
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400239
240 soi.msg = NULL; // prevent closing of RMR stuff on soi destroy
241}
242
243/*
244 Move Assignment operator. Move the message data to the existing object
245 ensure the object reference is cleaned up, and ensuring that the source
246 object references are removed.
247*/
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400248Alarm& xapp::Alarm::operator=( Alarm&& soi ) noexcept {
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400249 if( this != &soi ) { // cannot do self assignment
250 // anything that needs to be freed/delted from soi, must be done here
251
252 msg = soi.msg; // move pointers and values
253 endpoint = soi.endpoint;
254 whid = soi.whid;
255
256 me_id = soi.me_id;
257 app_id = soi.app_id;
258 problem_id = soi.problem_id;
259 severity = soi.severity;
260 info = soi.info;
261 add_info = soi.add_info;
262
263 soi.msg = NULL; // prevent bad things when source is destroyed
264 }
265
266 return *this;
267}
268
269/*
270 Destroyer.
271*/
272xapp::Alarm::~Alarm() {
273
274 msg = NULL;
275}
276
277
278// ---- setters -------------------------------------------------
279
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400280void xapp::Alarm::Set_meid( const std::string& new_meid ) {
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400281 me_id = new_meid;
282}
283
284void xapp::Alarm::Set_severity( int new_sev ) {
285 switch( new_sev ) {
286 case Alarm::SEV_CRIT:
287 severity = "CRITICAL";
288 break;
289
290 case Alarm::SEV_MAJOR:
291 severity = "MAJOR";
292 break;
293
294 case Alarm::SEV_MINOR:
295 severity = "MINOR";
296 break;
297
298 case Alarm::SEV_WARN:
299 severity = "WARNING";
300 break;
301
302 case Alarm::SEV_CLEAR:
303 severity = "CLEARED";
304 break;
305
306 default:
307 severity = "DEFAULT";
308 break;
309 }
310}
311
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400312void xapp::Alarm::Set_appid( const std::string& new_id ) {
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400313 app_id = new_id;
314}
315
316void xapp::Alarm::Set_problem( int new_id ) {
317 problem_id = new_id;
318}
319
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400320void xapp::Alarm::Set_info( const std::string& new_info ) {
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400321 info = new_info;
322}
323
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400324void xapp::Alarm::Set_additional( const std::string& new_info ) {
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400325 add_info = new_info;
326}
327
328void xapp::Alarm::Set_whid( int new_whid ) {
329 whid = new_whid;
330}
331
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400332void xapp::Alarm::Dump() const {
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400333 fprintf( stderr, "Alarm: prob id: %d\n", problem_id );
334 fprintf( stderr, "Alarm: meid: %s\n", me_id.c_str() );
335 fprintf( stderr, "Alarm: app: %s\n", app_id.c_str() );
336 fprintf( stderr, "Alarm: info: %s\n", info.c_str() );
337 fprintf( stderr, "Alarm: ainfo: %s\n", add_info.c_str() );
338}
339
340// ------------------- getters ------------------------------------
341
342/*
343 Return the enpoint address string we have.
344*/
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400345std::string xapp::Alarm::Get_endpoint( ) const {
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400346 return endpoint;
347}
348
349// ------- message sending ---------------------------------------
350
351/*
352 Send a raise message with the alarm contents unchanged.
353*/
354bool xapp::Alarm::Raise( ) {
355 int used;
356 used = build_alarm( ACT_RAISE, msg->Get_payload(), msg->Get_available_size() );
357 msg->Wormhole_send( whid, RIC_ALARM, xapp::Message::NO_SUBID, used + 1, NULL );
358}
359
360/*
361 Additional prototypes allow for avoiding some setter calls when raising alarms.
362 Severity is one of our SEV_* constants. Problem is the caller's assigned
363 problem ID. Info and addional_info are user supplied data that is just passed
364 through.
365*/
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400366bool xapp::Alarm::Raise( int new_severity, int problem, const std::string& cinfo ) {
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400367 Set_severity( new_severity );
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400368 problem_id = problem;
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400369 info = cinfo;
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400370
371 Raise();
372}
373
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400374bool xapp::Alarm::Raise( int new_severity, int problem, const std::string& cinfo, const std::string& additional_info ) {
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400375 Set_severity( new_severity );
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400376 problem_id = problem;
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400377 info = cinfo;
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400378 this->add_info = additional_info;
379
380 Raise();
381}
382
383/*
384 Send a clear message with the contents of the alarm otherwise unchanged.
385*/
386bool xapp::Alarm::Clear( ) {
387 int used;
388
389 used = build_alarm( ACT_CLEAR, msg->Get_payload(), msg->Get_available_size() );
390 msg->Wormhole_send( whid, RIC_ALARM, xapp::Message::NO_SUBID, used + 1, NULL );
391}
392
393/*
394 Additional prototypes allow for avoiding some setter calls when raising alarms.
395 Severity is one of our SEV_* constants. Problem is the caller's assigned
396 problem ID. Info and addional_info are user supplied data that is just passed
397 through.
398*/
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400399bool xapp::Alarm::Clear( int new_severity, int problem, const std::string& cinfo ) {
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400400 Set_severity( new_severity );
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400401 problem_id = problem;
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400402 info = cinfo;
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400403
404 Clear();
405}
406
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400407bool xapp::Alarm::Clear( int new_severity, int problem, const std::string& cinfo, const std::string& additional_info ) {
E. Scott Danielsc85ac8b2020-08-19 09:51:33 -0400408 Set_severity( new_severity );
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400409 problem_id = problem;
E. Scott Daniels23d0e612020-09-17 15:46:48 -0400410 info = cinfo;
E. Scott Daniels6ef23e12020-07-15 08:03:22 -0400411 this->add_info = additional_info;
412
413 Clear();
414}
415
416
417/*
418 Send a clear-all message. The contents of the alarm are unaffected.
419*/
420bool xapp::Alarm::Clear_all( ) {
421 int used;
422
423 used = build_alarm( ACT_CLEAR_ALL, msg->Get_payload(), msg->Get_available_size() );
424 msg->Wormhole_send( whid, RIC_ALARM, xapp::Message::NO_SUBID, used + 1, NULL );
425}
426
427
428/*
429 This is a convenience function which sends a clear message followed by a
430 raise message. Alarm contents are not adjusted.
431*/
432bool xapp::Alarm::Raise_again( ) {
433 Clear();
434 Raise();
435}
436
437
438
439} // namespace