]> granicus.if.org Git - icinga2/blob - components/livestatus/servicestable.cpp
Add CompatUtility::GetModifiedAttributesList() for Livestatus.
[icinga2] / components / livestatus / servicestable.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org)    *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "livestatus/servicestable.h"
21 #include "livestatus/hoststable.h"
22 #include "livestatus/endpointstable.h"
23 #include "icinga/service.h"
24 #include "icinga/checkcommand.h"
25 #include "icinga/eventcommand.h"
26 #include "icinga/timeperiod.h"
27 #include "icinga/macroprocessor.h"
28 #include "icinga/icingaapplication.h"
29 #include "icinga/compatutility.h"
30 #include "base/dynamictype.h"
31 #include "base/objectlock.h"
32 #include "base/convert.h"
33 #include "base/utility.h"
34 #include <boost/foreach.hpp>
35 #include <boost/tuple/tuple.hpp>
36 #include <boost/algorithm/string/replace.hpp>
37
38 using namespace icinga;
39
40 ServicesTable::ServicesTable(void)
41 {
42         AddColumns(this);
43 }
44
45 void ServicesTable::AddColumns(Table *table, const String& prefix,
46     const Column::ObjectAccessor& objectAccessor)
47 {
48         table->AddColumn(prefix + "description", Column(&ServicesTable::ShortNameAccessor, objectAccessor));
49         table->AddColumn(prefix + "display_name", Column(&ServicesTable::DisplayNameAccessor, objectAccessor));
50         table->AddColumn(prefix + "check_command", Column(&ServicesTable::CheckCommandAccessor, objectAccessor));
51         table->AddColumn(prefix + "check_command_expanded", Column(&ServicesTable::CheckCommandExpandedAccessor, objectAccessor));
52         table->AddColumn(prefix + "event_handler", Column(&ServicesTable::EventHandlerAccessor, objectAccessor));
53         table->AddColumn(prefix + "plugin_output", Column(&ServicesTable::PluginOutputAccessor, objectAccessor));
54         table->AddColumn(prefix + "long_plugin_output", Column(&ServicesTable::LongPluginOutputAccessor, objectAccessor));
55         table->AddColumn(prefix + "perf_data", Column(&ServicesTable::PerfDataAccessor, objectAccessor));
56         table->AddColumn(prefix + "notification_period", Column(&ServicesTable::NotificationPeriodAccessor, objectAccessor));
57         table->AddColumn(prefix + "check_period", Column(&ServicesTable::CheckPeriodAccessor, objectAccessor));
58         table->AddColumn(prefix + "notes", Column(&ServicesTable::NotesAccessor, objectAccessor));
59         table->AddColumn(prefix + "notes_expanded", Column(&ServicesTable::NotesExpandedAccessor, objectAccessor));
60         table->AddColumn(prefix + "notes_url", Column(&ServicesTable::NotesUrlAccessor, objectAccessor));
61         table->AddColumn(prefix + "notes_url_expanded", Column(&ServicesTable::NotesUrlExpandedAccessor, objectAccessor));
62         table->AddColumn(prefix + "action_url", Column(&ServicesTable::ActionUrlAccessor, objectAccessor));
63         table->AddColumn(prefix + "action_url_expanded", Column(&ServicesTable::ActionUrlExpandedAccessor, objectAccessor));
64         table->AddColumn(prefix + "icon_image", Column(&ServicesTable::IconImageAccessor, objectAccessor));
65         table->AddColumn(prefix + "icon_image_expanded", Column(&ServicesTable::IconImageExpandedAccessor, objectAccessor));
66         table->AddColumn(prefix + "icon_image_alt", Column(&ServicesTable::IconImageAltAccessor, objectAccessor));
67         table->AddColumn(prefix + "initial_state", Column(&Table::EmptyStringAccessor, objectAccessor));
68         table->AddColumn(prefix + "max_check_attempts", Column(&ServicesTable::MaxCheckAttemptsAccessor, objectAccessor));
69         table->AddColumn(prefix + "current_attempt", Column(&ServicesTable::CurrentAttemptAccessor, objectAccessor));
70         table->AddColumn(prefix + "state", Column(&ServicesTable::StateAccessor, objectAccessor));
71         table->AddColumn(prefix + "has_been_checked", Column(&ServicesTable::HasBeenCheckedAccessor, objectAccessor));
72         table->AddColumn(prefix + "last_state", Column(&ServicesTable::LastStateAccessor, objectAccessor));
73         table->AddColumn(prefix + "last_hard_state", Column(&ServicesTable::LastHardStateAccessor, objectAccessor));
74         table->AddColumn(prefix + "state_type", Column(&ServicesTable::StateTypeAccessor, objectAccessor));
75         table->AddColumn(prefix + "check_type", Column(&ServicesTable::CheckTypeAccessor, objectAccessor));
76         table->AddColumn(prefix + "acknowledged", Column(&ServicesTable::AcknowledgedAccessor, objectAccessor));
77         table->AddColumn(prefix + "acknowledgement_type", Column(&ServicesTable::AcknowledgementTypeAccessor, objectAccessor));
78         table->AddColumn(prefix + "no_more_notifications", Column(&ServicesTable::NoMoreNotificationsAccessor, objectAccessor));
79         table->AddColumn(prefix + "last_time_ok", Column(&ServicesTable::LastTimeOkAccessor, objectAccessor));
80         table->AddColumn(prefix + "last_time_warning", Column(&ServicesTable::LastTimeWarningAccessor, objectAccessor));
81         table->AddColumn(prefix + "last_time_critical", Column(&ServicesTable::LastTimeCriticalAccessor, objectAccessor));
82         table->AddColumn(prefix + "last_time_unknown", Column(&ServicesTable::LastTimeUnknownAccessor, objectAccessor));
83         table->AddColumn(prefix + "last_check", Column(&ServicesTable::LastCheckAccessor, objectAccessor));
84         table->AddColumn(prefix + "next_check", Column(&ServicesTable::NextCheckAccessor, objectAccessor));
85         table->AddColumn(prefix + "last_notification", Column(&ServicesTable::LastNotificationAccessor, objectAccessor));
86         table->AddColumn(prefix + "next_notification", Column(&ServicesTable::NextNotificationAccessor, objectAccessor));
87         table->AddColumn(prefix + "current_notification_number", Column(&ServicesTable::CurrentNotificationNumberAccessor, objectAccessor));
88         table->AddColumn(prefix + "last_state_change", Column(&ServicesTable::LastStateChangeAccessor, objectAccessor));
89         table->AddColumn(prefix + "last_hard_state_change", Column(&ServicesTable::LastHardStateChangeAccessor, objectAccessor));
90         table->AddColumn(prefix + "scheduled_downtime_depth", Column(&ServicesTable::ScheduledDowntimeDepthAccessor, objectAccessor));
91         table->AddColumn(prefix + "is_flapping", Column(&ServicesTable::IsFlappingAccessor, objectAccessor));
92         table->AddColumn(prefix + "checks_enabled", Column(&ServicesTable::ChecksEnabledAccessor, objectAccessor));
93         table->AddColumn(prefix + "accept_passive_checks", Column(&ServicesTable::AcceptPassiveChecksAccessor, objectAccessor));
94         table->AddColumn(prefix + "event_handler_enabled", Column(&ServicesTable::EventHandlerEnabledAccessor, objectAccessor));
95         table->AddColumn(prefix + "notifications_enabled", Column(&ServicesTable::NotificationsEnabledAccessor, objectAccessor));
96         table->AddColumn(prefix + "process_performance_data", Column(&ServicesTable::ProcessPerformanceDataAccessor, objectAccessor));
97         table->AddColumn(prefix + "is_executing", Column(&Table::ZeroAccessor, objectAccessor));
98         table->AddColumn(prefix + "active_checks_enabled", Column(&ServicesTable::ActiveChecksEnabledAccessor, objectAccessor));
99         table->AddColumn(prefix + "check_options", Column(&ServicesTable::CheckOptionsAccessor, objectAccessor));
100         table->AddColumn(prefix + "flap_detection_enabled", Column(&ServicesTable::FlapDetectionEnabledAccessor, objectAccessor));
101         table->AddColumn(prefix + "check_freshness", Column(&ServicesTable::CheckFreshnessAccessor, objectAccessor));
102         table->AddColumn(prefix + "obsess_over_service", Column(&Table::ZeroAccessor, objectAccessor));
103         table->AddColumn(prefix + "modified_attributes", Column(&ServicesTable::ModifiedAttributesAccessor, objectAccessor));
104         table->AddColumn(prefix + "modified_attributes_list", Column(&ServicesTable::ModifiedAttributesListAccessor, objectAccessor));
105         table->AddColumn(prefix + "pnpgraph_present", Column(&Table::ZeroAccessor, objectAccessor));
106         table->AddColumn(prefix + "staleness", Column(&ServicesTable::StalenessAccessor, objectAccessor));
107         table->AddColumn(prefix + "check_interval", Column(&ServicesTable::CheckIntervalAccessor, objectAccessor));
108         table->AddColumn(prefix + "retry_interval", Column(&ServicesTable::RetryIntervalAccessor, objectAccessor));
109         table->AddColumn(prefix + "notification_interval", Column(&ServicesTable::NotificationIntervalAccessor, objectAccessor));
110         table->AddColumn(prefix + "first_notification_delay", Column(&Table::EmptyStringAccessor, objectAccessor));
111         table->AddColumn(prefix + "low_flap_threshold", Column(&ServicesTable::LowFlapThresholdAccessor, objectAccessor));
112         table->AddColumn(prefix + "high_flap_threshold", Column(&ServicesTable::HighFlapThresholdAccessor, objectAccessor));
113         table->AddColumn(prefix + "latency", Column(&ServicesTable::LatencyAccessor, objectAccessor));
114         table->AddColumn(prefix + "execution_time", Column(&ServicesTable::ExecutionTimeAccessor, objectAccessor));
115         table->AddColumn(prefix + "percent_state_change", Column(&ServicesTable::PercentStateChangeAccessor, objectAccessor));
116         table->AddColumn(prefix + "in_check_period", Column(&ServicesTable::InCheckPeriodAccessor, objectAccessor));
117         table->AddColumn(prefix + "in_notification_period", Column(&ServicesTable::InNotificationPeriodAccessor, objectAccessor));
118         table->AddColumn(prefix + "contacts", Column(&ServicesTable::ContactsAccessor, objectAccessor));
119         table->AddColumn(prefix + "downtimes", Column(&ServicesTable::DowntimesAccessor, objectAccessor));
120         table->AddColumn(prefix + "downtimes_with_info", Column(&ServicesTable::DowntimesWithInfoAccessor, objectAccessor));
121         table->AddColumn(prefix + "comments", Column(&ServicesTable::CommentsAccessor, objectAccessor));
122         table->AddColumn(prefix + "comments_with_info", Column(&ServicesTable::CommentsWithInfoAccessor, objectAccessor));
123         table->AddColumn(prefix + "comments_with_extra_info", Column(&ServicesTable::CommentsWithExtraInfoAccessor, objectAccessor));
124         table->AddColumn(prefix + "custom_variable_names", Column(&ServicesTable::CustomVariableNamesAccessor, objectAccessor));
125         table->AddColumn(prefix + "custom_variable_values", Column(&ServicesTable::CustomVariableValuesAccessor, objectAccessor));
126         table->AddColumn(prefix + "custom_variables", Column(&ServicesTable::CustomVariablesAccessor, objectAccessor));
127         table->AddColumn(prefix + "groups", Column(&ServicesTable::GroupsAccessor, objectAccessor));
128         table->AddColumn(prefix + "contact_groups", Column(&ServicesTable::ContactGroupsAccessor, objectAccessor));
129         table->AddColumn(prefix + "check_source", Column(&ServicesTable::CheckSourceAccessor, objectAccessor));
130
131         HostsTable::AddColumns(table, "host_", boost::bind(&ServicesTable::HostAccessor, _1, objectAccessor));
132 }
133
134 String ServicesTable::GetName(void) const
135 {
136         return "services";
137 }
138
139 void ServicesTable::FetchRows(const AddRowFunction& addRowFn)
140 {
141         BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjects<Service>()) {
142                 addRowFn(service);
143         }
144 }
145
146 Object::Ptr ServicesTable::HostAccessor(const Value& row, const Column::ObjectAccessor& parentObjectAccessor)
147 {
148         Value service;
149
150         if (parentObjectAccessor)
151                 service = parentObjectAccessor(row);
152         else
153                 service = row;
154
155         Service::Ptr svc = static_cast<Service::Ptr>(service);
156
157         if (!svc)
158                 return Object::Ptr();
159
160         return svc->GetHost();
161 }
162
163 Value ServicesTable::ShortNameAccessor(const Value& row)
164 {
165         Service::Ptr service = static_cast<Service::Ptr>(row);
166
167         if (!service)
168                 return Empty;
169
170         return service->GetShortName();
171 }
172
173 Value ServicesTable::DisplayNameAccessor(const Value& row)
174 {
175         Service::Ptr service = static_cast<Service::Ptr>(row);
176
177         if (!service)
178                 return Empty;
179
180         return service->GetDisplayName();
181 }
182
183 Value ServicesTable::CheckCommandAccessor(const Value& row)
184 {
185         Service::Ptr service = static_cast<Service::Ptr>(row);
186
187         if (!service)
188                 return Empty;
189
190         CheckCommand::Ptr checkcommand = service->GetCheckCommand();
191
192         if (checkcommand)
193                 return checkcommand->GetName(); /* this is the name without '!' args */
194
195         return Empty;
196 }
197
198 Value ServicesTable::CheckCommandExpandedAccessor(const Value& row)
199 {
200         Service::Ptr service = static_cast<Service::Ptr>(row);
201
202         if (!service)
203                 return Empty;
204
205         CheckCommand::Ptr checkcommand = service->GetCheckCommand();
206
207         if (checkcommand)
208                 return checkcommand->GetName(); /* this is the name without '!' args */
209
210         return Empty;
211 }
212
213 Value ServicesTable::EventHandlerAccessor(const Value& row)
214 {
215         Service::Ptr service = static_cast<Service::Ptr>(row);
216
217         if (!service)
218                 return Empty;
219
220         EventCommand::Ptr eventcommand = service->GetEventCommand();
221
222         if (eventcommand)
223                 return eventcommand->GetName();
224
225         return Empty;
226 }
227
228 Value ServicesTable::PluginOutputAccessor(const Value& row)
229 {
230         Service::Ptr service = static_cast<Service::Ptr>(row);
231
232         if (!service)
233                 return Empty;
234
235         String output;
236         CheckResult::Ptr cr = service->GetLastCheckResult();
237
238         if (cr)
239                 output = CompatUtility::GetCheckResultOutput(cr);
240
241         return output;
242 }
243
244 Value ServicesTable::LongPluginOutputAccessor(const Value& row)
245 {
246         Service::Ptr service = static_cast<Service::Ptr>(row);
247
248         if (!service)
249                 return Empty;
250
251         String long_output;
252         CheckResult::Ptr cr = service->GetLastCheckResult();
253
254         if (cr)
255                 long_output = CompatUtility::GetCheckResultLongOutput(cr);
256
257         return long_output;
258 }
259
260 Value ServicesTable::PerfDataAccessor(const Value& row)
261 {
262         Service::Ptr service = static_cast<Service::Ptr>(row);
263
264         if (!service)
265                 return Empty;
266
267         String perfdata;
268         CheckResult::Ptr cr = service->GetLastCheckResult();
269
270         if (cr)
271                 perfdata = CompatUtility::GetCheckResultPerfdata(cr);
272
273         return perfdata;
274 }
275
276 Value ServicesTable::NotificationPeriodAccessor(const Value& row)
277 {
278         Service::Ptr service = static_cast<Service::Ptr>(row);
279
280         if (!service)
281                 return Empty;
282
283         return CompatUtility::GetCheckableNotificationNotificationPeriod(service);
284 }
285
286 Value ServicesTable::CheckPeriodAccessor(const Value& row)
287 {
288         Service::Ptr service = static_cast<Service::Ptr>(row);
289
290         if (!service)
291                 return Empty;
292
293         return CompatUtility::GetCheckableCheckPeriod(service);
294 }
295
296 Value ServicesTable::NotesAccessor(const Value& row)
297 {
298         Service::Ptr service = static_cast<Service::Ptr>(row);
299
300         if (!service)
301                 return Empty;
302
303         return service->GetNotes();
304 }
305
306 Value ServicesTable::NotesExpandedAccessor(const Value& row)
307 {
308         Service::Ptr service = static_cast<Service::Ptr>(row);
309
310         if (!service)
311                 return Empty;
312
313         MacroProcessor::ResolverList resolvers;
314         resolvers.push_back(std::make_pair("service", service));
315         resolvers.push_back(std::make_pair("host", service->GetHost()));
316         resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
317
318         return MacroProcessor::ResolveMacros(service->GetNotes(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd);
319 }
320
321 Value ServicesTable::NotesUrlAccessor(const Value& row)
322 {
323         Service::Ptr service = static_cast<Service::Ptr>(row);
324
325         if (!service)
326                 return Empty;
327
328         return service->GetNotesUrl();
329 }
330
331 Value ServicesTable::NotesUrlExpandedAccessor(const Value& row)
332 {
333         Service::Ptr service = static_cast<Service::Ptr>(row);
334
335         if (!service)
336                 return Empty;
337
338         MacroProcessor::ResolverList resolvers;
339         resolvers.push_back(std::make_pair("service", service));
340         resolvers.push_back(std::make_pair("host", service->GetHost()));
341         resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
342
343         return MacroProcessor::ResolveMacros(service->GetNotesUrl(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd);
344 }
345
346 Value ServicesTable::ActionUrlAccessor(const Value& row)
347 {
348         Service::Ptr service = static_cast<Service::Ptr>(row);
349
350         if (!service)
351                 return Empty;
352
353         return service->GetActionUrl();
354 }
355
356 Value ServicesTable::ActionUrlExpandedAccessor(const Value& row)
357 {
358         Service::Ptr service = static_cast<Service::Ptr>(row);
359
360         if (!service)
361                 return Empty;
362
363         MacroProcessor::ResolverList resolvers;
364         resolvers.push_back(std::make_pair("service", service));
365         resolvers.push_back(std::make_pair("host", service->GetHost()));
366         resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
367
368         return MacroProcessor::ResolveMacros(service->GetActionUrl(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd);
369 }
370
371 Value ServicesTable::IconImageAccessor(const Value& row)
372 {
373         Service::Ptr service = static_cast<Service::Ptr>(row);
374
375         if (!service)
376                 return Empty;
377
378         return service->GetIconImage();
379 }
380
381 Value ServicesTable::IconImageExpandedAccessor(const Value& row)
382 {
383         Service::Ptr service = static_cast<Service::Ptr>(row);
384
385         if (!service)
386                 return Empty;
387
388         MacroProcessor::ResolverList resolvers;
389         resolvers.push_back(std::make_pair("service", service));
390         resolvers.push_back(std::make_pair("host", service->GetHost()));
391         resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
392
393         return MacroProcessor::ResolveMacros(service->GetIconImage(), resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd);
394 }
395
396 Value ServicesTable::IconImageAltAccessor(const Value& row)
397 {
398         Service::Ptr service = static_cast<Service::Ptr>(row);
399
400         if (!service)
401                 return Empty;
402
403         return service->GetIconImageAlt();
404 }
405
406 Value ServicesTable::MaxCheckAttemptsAccessor(const Value& row)
407 {
408         Service::Ptr service = static_cast<Service::Ptr>(row);
409
410         if (!service)
411                 return Empty;
412
413         return service->GetMaxCheckAttempts();
414 }
415
416 Value ServicesTable::CurrentAttemptAccessor(const Value& row)
417 {
418         Service::Ptr service = static_cast<Service::Ptr>(row);
419
420         if (!service)
421                 return Empty;
422
423         return service->GetCheckAttempt();
424 }
425
426 Value ServicesTable::StateAccessor(const Value& row)
427 {
428         Service::Ptr service = static_cast<Service::Ptr>(row);
429
430         if (!service)
431                 return Empty;
432
433         return service->GetState();
434 }
435
436 Value ServicesTable::HasBeenCheckedAccessor(const Value& row)
437 {
438         Service::Ptr service = static_cast<Service::Ptr>(row);
439
440         if (!service)
441                 return Empty;
442
443         return CompatUtility::GetCheckableHasBeenChecked(service);
444 }
445
446 Value ServicesTable::LastStateAccessor(const Value& row)
447 {
448         Service::Ptr service = static_cast<Service::Ptr>(row);
449
450         if (!service)
451                 return Empty;
452
453         return service->GetLastState();
454 }
455
456 Value ServicesTable::LastHardStateAccessor(const Value& row)
457 {
458         Service::Ptr service = static_cast<Service::Ptr>(row);
459
460         if (!service)
461                 return Empty;
462
463         return service->GetLastHardState();
464 }
465
466 Value ServicesTable::StateTypeAccessor(const Value& row)
467 {
468         Service::Ptr service = static_cast<Service::Ptr>(row);
469
470         if (!service)
471                 return Empty;
472
473         return service->GetStateType();
474 }
475
476 Value ServicesTable::CheckTypeAccessor(const Value& row)
477 {
478         Service::Ptr service = static_cast<Service::Ptr>(row);
479
480         if (!service)
481                 return Empty;
482
483         return CompatUtility::GetCheckableCheckType(service);
484 }
485
486 Value ServicesTable::AcknowledgedAccessor(const Value& row)
487 {
488         Service::Ptr service = static_cast<Service::Ptr>(row);
489
490         if (!service)
491                 return Empty;
492
493         return CompatUtility::GetCheckableIsAcknowledged(service);
494 }
495
496 Value ServicesTable::AcknowledgementTypeAccessor(const Value& row)
497 {
498         Service::Ptr service = static_cast<Service::Ptr>(row);
499
500         if (!service)
501                 return Empty;
502
503         /* important: lock acknowledgements */
504         ObjectLock olock(service);
505
506         return static_cast<int>(service->GetAcknowledgement());
507 }
508
509 Value ServicesTable::NoMoreNotificationsAccessor(const Value& row)
510 {
511         Service::Ptr service = static_cast<Service::Ptr>(row);
512
513         if (!service)
514                 return Empty;
515
516         return CompatUtility::GetCheckableNoMoreNotifications(service);
517 }
518
519 Value ServicesTable::LastTimeOkAccessor(const Value& row)
520 {
521         Service::Ptr service = static_cast<Service::Ptr>(row);
522
523         if (!service)
524                 return Empty;
525
526         return static_cast<int>(service->GetLastStateOK());
527 }
528
529 Value ServicesTable::LastTimeWarningAccessor(const Value& row)
530 {
531         Service::Ptr service = static_cast<Service::Ptr>(row);
532
533         if (!service)
534                 return Empty;
535
536         return static_cast<int>(service->GetLastStateWarning());
537 }
538
539 Value ServicesTable::LastTimeCriticalAccessor(const Value& row)
540 {
541         Service::Ptr service = static_cast<Service::Ptr>(row);
542
543         if (!service)
544                 return Empty;
545
546         return static_cast<int>(service->GetLastStateCritical());
547 }
548
549 Value ServicesTable::LastTimeUnknownAccessor(const Value& row)
550 {
551         Service::Ptr service = static_cast<Service::Ptr>(row);
552
553         if (!service)
554                 return Empty;
555
556         return static_cast<int>(service->GetLastStateUnknown());
557 }
558
559 Value ServicesTable::LastCheckAccessor(const Value& row)
560 {
561         Service::Ptr service = static_cast<Service::Ptr>(row);
562
563         if (!service)
564                 return Empty;
565
566         return static_cast<int>(service->GetLastCheck());
567 }
568
569 Value ServicesTable::NextCheckAccessor(const Value& row)
570 {
571         Service::Ptr service = static_cast<Service::Ptr>(row);
572
573         if (!service)
574                 return Empty;
575
576         return static_cast<int>(service->GetNextCheck());
577 }
578
579 Value ServicesTable::LastNotificationAccessor(const Value& row)
580 {
581         Service::Ptr service = static_cast<Service::Ptr>(row);
582
583         if (!service)
584                 return Empty;
585
586         return CompatUtility::GetCheckableNotificationLastNotification(service);
587 }
588
589 Value ServicesTable::NextNotificationAccessor(const Value& row)
590 {
591         Service::Ptr service = static_cast<Service::Ptr>(row);
592
593         if (!service)
594                 return Empty;
595
596         return CompatUtility::GetCheckableNotificationNextNotification(service);
597 }
598
599 Value ServicesTable::CurrentNotificationNumberAccessor(const Value& row)
600 {
601         Service::Ptr service = static_cast<Service::Ptr>(row);
602
603         if (!service)
604                 return Empty;
605
606         return CompatUtility::GetCheckableNotificationNotificationNumber(service);
607 }
608
609 Value ServicesTable::LastStateChangeAccessor(const Value& row)
610 {
611         Service::Ptr service = static_cast<Service::Ptr>(row);
612
613         if (!service)
614                 return Empty;
615
616         return static_cast<int>(service->GetLastStateChange());
617 }
618
619 Value ServicesTable::LastHardStateChangeAccessor(const Value& row)
620 {
621         Service::Ptr service = static_cast<Service::Ptr>(row);
622
623         if (!service)
624                 return Empty;
625
626         return static_cast<int>(service->GetLastHardStateChange());
627 }
628
629 Value ServicesTable::ScheduledDowntimeDepthAccessor(const Value& row)
630 {
631         Service::Ptr service = static_cast<Service::Ptr>(row);
632
633         if (!service)
634                 return Empty;
635
636         return service->GetDowntimeDepth();
637 }
638
639 Value ServicesTable::IsFlappingAccessor(const Value& row)
640 {
641         Service::Ptr service = static_cast<Service::Ptr>(row);
642
643         if (!service)
644                 return Empty;
645
646         return service->IsFlapping();
647 }
648
649 Value ServicesTable::ChecksEnabledAccessor(const Value& row)
650 {
651         Service::Ptr service = static_cast<Service::Ptr>(row);
652
653         if (!service)
654                 return Empty;
655
656         return CompatUtility::GetCheckableActiveChecksEnabled(service);
657 }
658
659 Value ServicesTable::AcceptPassiveChecksAccessor(const Value& row)
660 {
661         Service::Ptr service = static_cast<Service::Ptr>(row);
662
663         if (!service)
664                 return Empty;
665
666         return CompatUtility::GetCheckablePassiveChecksEnabled(service);
667 }
668
669 Value ServicesTable::EventHandlerEnabledAccessor(const Value& row)
670 {
671         Service::Ptr service = static_cast<Service::Ptr>(row);
672
673         if (!service)
674                 return Empty;
675
676         return CompatUtility::GetCheckableEventHandlerEnabled(service);
677 }
678
679 Value ServicesTable::NotificationsEnabledAccessor(const Value& row)
680 {
681         Service::Ptr service = static_cast<Service::Ptr>(row);
682
683         if (!service)
684                 return Empty;
685
686         return CompatUtility::GetCheckableNotificationsEnabled(service);
687 }
688
689 Value ServicesTable::ProcessPerformanceDataAccessor(const Value& row)
690 {
691         Service::Ptr service = static_cast<Service::Ptr>(row);
692
693         if (!service)
694                 return Empty;
695
696         return CompatUtility::GetCheckableProcessPerformanceData(service);
697 }
698
699 Value ServicesTable::ActiveChecksEnabledAccessor(const Value& row)
700 {
701         Service::Ptr service = static_cast<Service::Ptr>(row);
702
703         if (!service)
704                 return Empty;
705
706         return CompatUtility::GetCheckableActiveChecksEnabled(service);
707 }
708
709 Value ServicesTable::CheckOptionsAccessor(const Value& row)
710 {
711         /* TODO - forcexec, freshness, orphan, none */
712         return Empty;
713 }
714
715 Value ServicesTable::FlapDetectionEnabledAccessor(const Value& row)
716 {
717         Service::Ptr service = static_cast<Service::Ptr>(row);
718
719         if (!service)
720                 return Empty;
721
722         return CompatUtility::GetCheckableFlapDetectionEnabled(service);
723 }
724
725 Value ServicesTable::CheckFreshnessAccessor(const Value& row)
726 {
727         Service::Ptr service = static_cast<Service::Ptr>(row);
728
729         if (!service)
730                 return Empty;
731
732         return CompatUtility::GetCheckableFreshnessChecksEnabled(service);
733 }
734
735 Value ServicesTable::ModifiedAttributesAccessor(const Value& row)
736 {
737         Service::Ptr service = static_cast<Service::Ptr>(row);
738
739         if (!service)
740                 return Empty;
741
742         return service->GetModifiedAttributes();
743 }
744
745 Value ServicesTable::ModifiedAttributesListAccessor(const Value& row)
746 {
747         Service::Ptr service = static_cast<Service::Ptr>(row);
748
749         if (!service)
750                 return Empty;
751
752         return CompatUtility::GetModifiedAttributesList(service);
753 }
754
755 Value ServicesTable::StalenessAccessor(const Value& row)
756 {
757         Service::Ptr service = static_cast<Service::Ptr>(row);
758
759         if (!service)
760                 return Empty;
761
762         return CompatUtility::GetCheckableStaleness(service);
763 }
764
765 Value ServicesTable::CheckIntervalAccessor(const Value& row)
766 {
767         Service::Ptr service = static_cast<Service::Ptr>(row);
768
769         if (!service)
770                 return Empty;
771
772         return CompatUtility::GetCheckableCheckInterval(service);
773 }
774
775 Value ServicesTable::RetryIntervalAccessor(const Value& row)
776 {
777         Service::Ptr service = static_cast<Service::Ptr>(row);
778
779         if (!service)
780                 return Empty;
781
782         return CompatUtility::GetCheckableRetryInterval(service);
783 }
784
785 Value ServicesTable::NotificationIntervalAccessor(const Value& row)
786 {
787         Service::Ptr service = static_cast<Service::Ptr>(row);
788
789         if (!service)
790                 return Empty;
791
792         return CompatUtility::GetCheckableNotificationNotificationInterval(service);
793 }
794
795 Value ServicesTable::LowFlapThresholdAccessor(const Value& row)
796 {
797         Service::Ptr service = static_cast<Service::Ptr>(row);
798
799         if (!service)
800                 return Empty;
801
802         return CompatUtility::GetCheckableLowFlapThreshold(service);
803 }
804
805 Value ServicesTable::HighFlapThresholdAccessor(const Value& row)
806 {
807         Service::Ptr service = static_cast<Service::Ptr>(row);
808
809         if (!service)
810                 return Empty;
811
812         return CompatUtility::GetCheckableHighFlapThreshold(service);
813 }
814
815 Value ServicesTable::LatencyAccessor(const Value& row)
816 {
817         Service::Ptr service = static_cast<Service::Ptr>(row);
818
819         if (!service)
820                 return Empty;
821
822         return (Service::CalculateLatency(service->GetLastCheckResult()));
823 }
824
825 Value ServicesTable::ExecutionTimeAccessor(const Value& row)
826 {
827         Service::Ptr service = static_cast<Service::Ptr>(row);
828
829         if (!service)
830                 return Empty;
831
832         return (Service::CalculateExecutionTime(service->GetLastCheckResult()));
833 }
834
835 Value ServicesTable::PercentStateChangeAccessor(const Value& row)
836 {
837         Service::Ptr service = static_cast<Service::Ptr>(row);
838
839         if (!service)
840                 return Empty;
841
842         return CompatUtility::GetCheckablePercentStateChange(service);
843 }
844
845 Value ServicesTable::InCheckPeriodAccessor(const Value& row)
846 {
847         Service::Ptr service = static_cast<Service::Ptr>(row);
848
849         if (!service)
850                 return Empty;
851
852         return CompatUtility::GetCheckableInCheckPeriod(service);
853 }
854
855 Value ServicesTable::InNotificationPeriodAccessor(const Value& row)
856 {
857         Service::Ptr service = static_cast<Service::Ptr>(row);
858
859         if (!service)
860                 return Empty;
861
862         return CompatUtility::GetCheckableInNotificationPeriod(service);
863 }
864
865 Value ServicesTable::ContactsAccessor(const Value& row)
866 {
867         Service::Ptr service = static_cast<Service::Ptr>(row);
868
869         if (!service)
870                 return Empty;
871
872         Array::Ptr contact_names = make_shared<Array>();
873
874         BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(service)) {
875                 contact_names->Add(user->GetName());
876         }
877
878         return contact_names;
879 }
880
881 Value ServicesTable::DowntimesAccessor(const Value& row)
882 {
883         Service::Ptr service = static_cast<Service::Ptr>(row);
884
885         if (!service)
886                 return Empty;
887
888         Dictionary::Ptr downtimes = service->GetDowntimes();
889
890         Array::Ptr ids = make_shared<Array>();
891
892         ObjectLock olock(downtimes);
893
894         String id;
895         Downtime::Ptr downtime;
896         BOOST_FOREACH(tie(id, downtime), downtimes) {
897
898                 if (!downtime)
899                         continue;
900
901                 if (downtime->IsExpired())
902                         continue;
903
904                 ids->Add(downtime->GetLegacyId());
905         }
906
907         return ids;
908 }
909
910 Value ServicesTable::DowntimesWithInfoAccessor(const Value& row)
911 {
912         Service::Ptr service = static_cast<Service::Ptr>(row);
913
914         if (!service)
915                 return Empty;
916
917         Dictionary::Ptr downtimes = service->GetDowntimes();
918
919         Array::Ptr ids = make_shared<Array>();
920
921         ObjectLock olock(downtimes);
922
923         String id;
924         Downtime::Ptr downtime;
925         BOOST_FOREACH(tie(id, downtime), downtimes) {
926
927                 if (!downtime)
928                         continue;
929
930                 if (downtime->IsExpired())
931                         continue;
932
933                 Array::Ptr downtime_info = make_shared<Array>();
934                 downtime_info->Add(downtime->GetLegacyId());
935                 downtime_info->Add(downtime->GetAuthor());
936                 downtime_info->Add(downtime->GetComment());
937                 ids->Add(downtime_info);
938         }
939
940         return ids;
941 }
942
943 Value ServicesTable::CommentsAccessor(const Value& row)
944 {
945         Service::Ptr service = static_cast<Service::Ptr>(row);
946
947         if (!service)
948                 return Empty;
949
950         Dictionary::Ptr comments = service->GetComments();
951
952         Array::Ptr ids = make_shared<Array>();
953
954         ObjectLock olock(comments);
955
956         String id;
957         Comment::Ptr comment;
958         BOOST_FOREACH(tie(id, comment), comments) {
959
960                 if (!comment)
961                         continue;
962
963                 if (comment->IsExpired())
964                         continue;
965
966                 ids->Add(comment->GetLegacyId());
967         }
968
969         return ids;
970 }
971
972 Value ServicesTable::CommentsWithInfoAccessor(const Value& row)
973 {
974         Service::Ptr service = static_cast<Service::Ptr>(row);
975
976         if (!service)
977                 return Empty;
978
979         Dictionary::Ptr comments = service->GetComments();
980
981         Array::Ptr ids = make_shared<Array>();
982
983         ObjectLock olock(comments);
984
985         String id;
986         Comment::Ptr comment;
987         BOOST_FOREACH(tie(id, comment), comments) {
988
989                 if (!comment)
990                         continue;
991
992                 if (comment->IsExpired())
993                         continue;
994
995                 Array::Ptr comment_info = make_shared<Array>();
996                 comment_info->Add(comment->GetLegacyId());
997                 comment_info->Add(comment->GetAuthor());
998                 comment_info->Add(comment->GetText());
999                 ids->Add(comment_info);
1000         }
1001
1002         return ids;
1003 }
1004
1005 Value ServicesTable::CommentsWithExtraInfoAccessor(const Value& row)
1006 {
1007         Service::Ptr service = static_cast<Service::Ptr>(row);
1008
1009         if (!service)
1010                 return Empty;
1011
1012         Dictionary::Ptr comments = service->GetComments();
1013
1014         Array::Ptr ids = make_shared<Array>();
1015
1016         ObjectLock olock(comments);
1017
1018         String id;
1019         Comment::Ptr comment;
1020         BOOST_FOREACH(tie(id, comment), comments) {
1021
1022                 if (!comment)
1023                         continue;
1024
1025                 if (comment->IsExpired())
1026                         continue;
1027
1028                 Array::Ptr comment_info = make_shared<Array>();
1029                 comment_info->Add(comment->GetLegacyId());
1030                 comment_info->Add(comment->GetAuthor());
1031                 comment_info->Add(comment->GetText());
1032                 comment_info->Add(comment->GetEntryType());
1033                 comment_info->Add(static_cast<int>(comment->GetEntryTime()));
1034                 ids->Add(comment_info);
1035         }
1036
1037         return ids;
1038 }
1039
1040 Value ServicesTable::CustomVariableNamesAccessor(const Value& row)
1041 {
1042         Service::Ptr service = static_cast<Service::Ptr>(row);
1043
1044         if (!service)
1045                 return Empty;
1046
1047         Dictionary::Ptr vars;
1048
1049         {
1050                 ObjectLock olock(service);
1051                 vars = CompatUtility::GetCustomAttributeConfig(service);
1052         }
1053
1054         if (!vars)
1055                 return Empty;
1056
1057         Array::Ptr cv = make_shared<Array>();
1058
1059         String key;
1060         Value value;
1061         BOOST_FOREACH(tie(key, value), vars) {
1062                 cv->Add(key);
1063         }
1064
1065         return cv;
1066 }
1067
1068 Value ServicesTable::CustomVariableValuesAccessor(const Value& row)
1069 {
1070         Service::Ptr service = static_cast<Service::Ptr>(row);
1071
1072         if (!service)
1073                 return Empty;
1074
1075         Dictionary::Ptr vars;
1076
1077         {
1078                 ObjectLock olock(service);
1079                 vars = CompatUtility::GetCustomAttributeConfig(service);
1080         }
1081
1082         if (!vars)
1083                 return Empty;
1084
1085         Array::Ptr cv = make_shared<Array>();
1086
1087         String key;
1088         Value value;
1089         BOOST_FOREACH(tie(key, value), vars) {
1090                 cv->Add(value);
1091         }
1092
1093         return cv;
1094 }
1095
1096 Value ServicesTable::CustomVariablesAccessor(const Value& row)
1097 {
1098         Service::Ptr service = static_cast<Service::Ptr>(row);
1099
1100         if (!service)
1101                 return Empty;
1102
1103         Dictionary::Ptr vars;
1104
1105         {
1106                 ObjectLock olock(service);
1107                 vars = CompatUtility::GetCustomAttributeConfig(service);
1108         }
1109
1110         if (!vars)
1111                 return Empty;
1112
1113         Array::Ptr cv = make_shared<Array>();
1114
1115         String key;
1116         Value value;
1117         BOOST_FOREACH(tie(key, value), vars) {
1118                 Array::Ptr key_val = make_shared<Array>();
1119                 key_val->Add(key);
1120                 key_val->Add(value);
1121                 cv->Add(key_val);
1122         }
1123
1124         return cv;
1125 }
1126
1127 Value ServicesTable::GroupsAccessor(const Value& row)
1128 {
1129         Service::Ptr service = static_cast<Service::Ptr>(row);
1130
1131         if (!service)
1132                 return Empty;
1133
1134         Array::Ptr groups = service->GetGroups();
1135
1136         if (!groups)
1137                 return Empty;
1138
1139         return groups;
1140 }
1141
1142 Value ServicesTable::ContactGroupsAccessor(const Value& row)
1143 {
1144         Service::Ptr service = static_cast<Service::Ptr>(row);
1145
1146         if (!service)
1147                 return Empty;
1148
1149         Array::Ptr contactgroup_names = make_shared<Array>();
1150
1151         BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(service)) {
1152                 contactgroup_names->Add(usergroup->GetName());
1153         }
1154
1155         return contactgroup_names;
1156 }
1157
1158 Value ServicesTable::CheckSourceAccessor(const Value& row)
1159 {
1160         Service::Ptr service = static_cast<Service::Ptr>(row);
1161
1162         if (!service)
1163                 return Empty;
1164
1165         CheckResult::Ptr cr = service->GetLastCheckResult();
1166
1167         if (cr)
1168                 return cr->GetCheckSource();
1169
1170         return Empty;
1171 }
1172
1173