]> granicus.if.org Git - icinga2/blob - components/livestatus/servicestable.cpp
Use legacy attribute getters in interfaces.
[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         /* not supported */
748         return Empty;
749 }
750
751 Value ServicesTable::StalenessAccessor(const Value& row)
752 {
753         Service::Ptr service = static_cast<Service::Ptr>(row);
754
755         if (!service)
756                 return Empty;
757
758         return CompatUtility::GetCheckableStaleness(service);
759 }
760
761 Value ServicesTable::CheckIntervalAccessor(const Value& row)
762 {
763         Service::Ptr service = static_cast<Service::Ptr>(row);
764
765         if (!service)
766                 return Empty;
767
768         return CompatUtility::GetCheckableCheckInterval(service);
769 }
770
771 Value ServicesTable::RetryIntervalAccessor(const Value& row)
772 {
773         Service::Ptr service = static_cast<Service::Ptr>(row);
774
775         if (!service)
776                 return Empty;
777
778         return CompatUtility::GetCheckableRetryInterval(service);
779 }
780
781 Value ServicesTable::NotificationIntervalAccessor(const Value& row)
782 {
783         Service::Ptr service = static_cast<Service::Ptr>(row);
784
785         if (!service)
786                 return Empty;
787
788         return CompatUtility::GetCheckableNotificationNotificationInterval(service);
789 }
790
791 Value ServicesTable::LowFlapThresholdAccessor(const Value& row)
792 {
793         Service::Ptr service = static_cast<Service::Ptr>(row);
794
795         if (!service)
796                 return Empty;
797
798         return CompatUtility::GetCheckableLowFlapThreshold(service);
799 }
800
801 Value ServicesTable::HighFlapThresholdAccessor(const Value& row)
802 {
803         Service::Ptr service = static_cast<Service::Ptr>(row);
804
805         if (!service)
806                 return Empty;
807
808         return CompatUtility::GetCheckableHighFlapThreshold(service);
809 }
810
811 Value ServicesTable::LatencyAccessor(const Value& row)
812 {
813         Service::Ptr service = static_cast<Service::Ptr>(row);
814
815         if (!service)
816                 return Empty;
817
818         return (Service::CalculateLatency(service->GetLastCheckResult()));
819 }
820
821 Value ServicesTable::ExecutionTimeAccessor(const Value& row)
822 {
823         Service::Ptr service = static_cast<Service::Ptr>(row);
824
825         if (!service)
826                 return Empty;
827
828         return (Service::CalculateExecutionTime(service->GetLastCheckResult()));
829 }
830
831 Value ServicesTable::PercentStateChangeAccessor(const Value& row)
832 {
833         Service::Ptr service = static_cast<Service::Ptr>(row);
834
835         if (!service)
836                 return Empty;
837
838         return CompatUtility::GetCheckablePercentStateChange(service);
839 }
840
841 Value ServicesTable::InCheckPeriodAccessor(const Value& row)
842 {
843         Service::Ptr service = static_cast<Service::Ptr>(row);
844
845         if (!service)
846                 return Empty;
847
848         return CompatUtility::GetCheckableInCheckPeriod(service);
849 }
850
851 Value ServicesTable::InNotificationPeriodAccessor(const Value& row)
852 {
853         Service::Ptr service = static_cast<Service::Ptr>(row);
854
855         if (!service)
856                 return Empty;
857
858         return CompatUtility::GetCheckableInNotificationPeriod(service);
859 }
860
861 Value ServicesTable::ContactsAccessor(const Value& row)
862 {
863         Service::Ptr service = static_cast<Service::Ptr>(row);
864
865         if (!service)
866                 return Empty;
867
868         Array::Ptr contact_names = make_shared<Array>();
869
870         BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(service)) {
871                 contact_names->Add(user->GetName());
872         }
873
874         return contact_names;
875 }
876
877 Value ServicesTable::DowntimesAccessor(const Value& row)
878 {
879         Service::Ptr service = static_cast<Service::Ptr>(row);
880
881         if (!service)
882                 return Empty;
883
884         Dictionary::Ptr downtimes = service->GetDowntimes();
885
886         Array::Ptr ids = make_shared<Array>();
887
888         ObjectLock olock(downtimes);
889
890         String id;
891         Downtime::Ptr downtime;
892         BOOST_FOREACH(tie(id, downtime), downtimes) {
893
894                 if (!downtime)
895                         continue;
896
897                 if (downtime->IsExpired())
898                         continue;
899
900                 ids->Add(downtime->GetLegacyId());
901         }
902
903         return ids;
904 }
905
906 Value ServicesTable::DowntimesWithInfoAccessor(const Value& row)
907 {
908         Service::Ptr service = static_cast<Service::Ptr>(row);
909
910         if (!service)
911                 return Empty;
912
913         Dictionary::Ptr downtimes = service->GetDowntimes();
914
915         Array::Ptr ids = make_shared<Array>();
916
917         ObjectLock olock(downtimes);
918
919         String id;
920         Downtime::Ptr downtime;
921         BOOST_FOREACH(tie(id, downtime), downtimes) {
922
923                 if (!downtime)
924                         continue;
925
926                 if (downtime->IsExpired())
927                         continue;
928
929                 Array::Ptr downtime_info = make_shared<Array>();
930                 downtime_info->Add(downtime->GetLegacyId());
931                 downtime_info->Add(downtime->GetAuthor());
932                 downtime_info->Add(downtime->GetComment());
933                 ids->Add(downtime_info);
934         }
935
936         return ids;
937 }
938
939 Value ServicesTable::CommentsAccessor(const Value& row)
940 {
941         Service::Ptr service = static_cast<Service::Ptr>(row);
942
943         if (!service)
944                 return Empty;
945
946         Dictionary::Ptr comments = service->GetComments();
947
948         Array::Ptr ids = make_shared<Array>();
949
950         ObjectLock olock(comments);
951
952         String id;
953         Comment::Ptr comment;
954         BOOST_FOREACH(tie(id, comment), comments) {
955
956                 if (!comment)
957                         continue;
958
959                 if (comment->IsExpired())
960                         continue;
961
962                 ids->Add(comment->GetLegacyId());
963         }
964
965         return ids;
966 }
967
968 Value ServicesTable::CommentsWithInfoAccessor(const Value& row)
969 {
970         Service::Ptr service = static_cast<Service::Ptr>(row);
971
972         if (!service)
973                 return Empty;
974
975         Dictionary::Ptr comments = service->GetComments();
976
977         Array::Ptr ids = make_shared<Array>();
978
979         ObjectLock olock(comments);
980
981         String id;
982         Comment::Ptr comment;
983         BOOST_FOREACH(tie(id, comment), comments) {
984
985                 if (!comment)
986                         continue;
987
988                 if (comment->IsExpired())
989                         continue;
990
991                 Array::Ptr comment_info = make_shared<Array>();
992                 comment_info->Add(comment->GetLegacyId());
993                 comment_info->Add(comment->GetAuthor());
994                 comment_info->Add(comment->GetText());
995                 ids->Add(comment_info);
996         }
997
998         return ids;
999 }
1000
1001 Value ServicesTable::CommentsWithExtraInfoAccessor(const Value& row)
1002 {
1003         Service::Ptr service = static_cast<Service::Ptr>(row);
1004
1005         if (!service)
1006                 return Empty;
1007
1008         Dictionary::Ptr comments = service->GetComments();
1009
1010         Array::Ptr ids = make_shared<Array>();
1011
1012         ObjectLock olock(comments);
1013
1014         String id;
1015         Comment::Ptr comment;
1016         BOOST_FOREACH(tie(id, comment), comments) {
1017
1018                 if (!comment)
1019                         continue;
1020
1021                 if (comment->IsExpired())
1022                         continue;
1023
1024                 Array::Ptr comment_info = make_shared<Array>();
1025                 comment_info->Add(comment->GetLegacyId());
1026                 comment_info->Add(comment->GetAuthor());
1027                 comment_info->Add(comment->GetText());
1028                 comment_info->Add(comment->GetEntryType());
1029                 comment_info->Add(static_cast<int>(comment->GetEntryTime()));
1030                 ids->Add(comment_info);
1031         }
1032
1033         return ids;
1034 }
1035
1036 Value ServicesTable::CustomVariableNamesAccessor(const Value& row)
1037 {
1038         Service::Ptr service = static_cast<Service::Ptr>(row);
1039
1040         if (!service)
1041                 return Empty;
1042
1043         Dictionary::Ptr vars;
1044
1045         {
1046                 ObjectLock olock(service);
1047                 vars = CompatUtility::GetCustomAttributeConfig(service);
1048         }
1049
1050         if (!vars)
1051                 return Empty;
1052
1053         Array::Ptr cv = make_shared<Array>();
1054
1055         String key;
1056         Value value;
1057         BOOST_FOREACH(tie(key, value), vars) {
1058                 cv->Add(key);
1059         }
1060
1061         return cv;
1062 }
1063
1064 Value ServicesTable::CustomVariableValuesAccessor(const Value& row)
1065 {
1066         Service::Ptr service = static_cast<Service::Ptr>(row);
1067
1068         if (!service)
1069                 return Empty;
1070
1071         Dictionary::Ptr vars;
1072
1073         {
1074                 ObjectLock olock(service);
1075                 vars = CompatUtility::GetCustomAttributeConfig(service);
1076         }
1077
1078         if (!vars)
1079                 return Empty;
1080
1081         Array::Ptr cv = make_shared<Array>();
1082
1083         String key;
1084         Value value;
1085         BOOST_FOREACH(tie(key, value), vars) {
1086                 cv->Add(value);
1087         }
1088
1089         return cv;
1090 }
1091
1092 Value ServicesTable::CustomVariablesAccessor(const Value& row)
1093 {
1094         Service::Ptr service = static_cast<Service::Ptr>(row);
1095
1096         if (!service)
1097                 return Empty;
1098
1099         Dictionary::Ptr vars;
1100
1101         {
1102                 ObjectLock olock(service);
1103                 vars = CompatUtility::GetCustomAttributeConfig(service);
1104         }
1105
1106         if (!vars)
1107                 return Empty;
1108
1109         Array::Ptr cv = make_shared<Array>();
1110
1111         String key;
1112         Value value;
1113         BOOST_FOREACH(tie(key, value), vars) {
1114                 Array::Ptr key_val = make_shared<Array>();
1115                 key_val->Add(key);
1116                 key_val->Add(value);
1117                 cv->Add(key_val);
1118         }
1119
1120         return cv;
1121 }
1122
1123 Value ServicesTable::GroupsAccessor(const Value& row)
1124 {
1125         Service::Ptr service = static_cast<Service::Ptr>(row);
1126
1127         if (!service)
1128                 return Empty;
1129
1130         Array::Ptr groups = service->GetGroups();
1131
1132         if (!groups)
1133                 return Empty;
1134
1135         return groups;
1136 }
1137
1138 Value ServicesTable::ContactGroupsAccessor(const Value& row)
1139 {
1140         Service::Ptr service = static_cast<Service::Ptr>(row);
1141
1142         if (!service)
1143                 return Empty;
1144
1145         Array::Ptr contactgroup_names = make_shared<Array>();
1146
1147         BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(service)) {
1148                 contactgroup_names->Add(usergroup->GetName());
1149         }
1150
1151         return contactgroup_names;
1152 }
1153
1154 Value ServicesTable::CheckSourceAccessor(const Value& row)
1155 {
1156         Service::Ptr service = static_cast<Service::Ptr>(row);
1157
1158         if (!service)
1159                 return Empty;
1160
1161         CheckResult::Ptr cr = service->GetLastCheckResult();
1162
1163         if (cr)
1164                 return cr->GetCheckSource();
1165
1166         return Empty;
1167 }
1168
1169