]> granicus.if.org Git - icinga2/blob - components/livestatus/servicestable.cpp
Implement attributes for some well-known macros and allow macro recursion.
[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 CompatUtility::GetCustomAttributeConfig(service, "notes");
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         Value value = CompatUtility::GetCustomAttributeConfig(service, "notes");
319
320         return MacroProcessor::ResolveMacros(value, resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd);
321 }
322
323 Value ServicesTable::NotesUrlAccessor(const Value& row)
324 {
325         Service::Ptr service = static_cast<Service::Ptr>(row);
326
327         if (!service)
328                 return Empty;
329
330         return CompatUtility::GetCustomAttributeConfig(service, "notes_url");
331 }
332
333 Value ServicesTable::NotesUrlExpandedAccessor(const Value& row)
334 {
335         Service::Ptr service = static_cast<Service::Ptr>(row);
336
337         if (!service)
338                 return Empty;
339
340         MacroProcessor::ResolverList resolvers;
341         resolvers.push_back(std::make_pair("service", service));
342         resolvers.push_back(std::make_pair("host", service->GetHost()));
343         resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
344
345         Value value = CompatUtility::GetCustomAttributeConfig(service, "notes_url");
346
347         return MacroProcessor::ResolveMacros(value, resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd);
348 }
349
350 Value ServicesTable::ActionUrlAccessor(const Value& row)
351 {
352         Service::Ptr service = static_cast<Service::Ptr>(row);
353
354         if (!service)
355                 return Empty;
356
357         return CompatUtility::GetCustomAttributeConfig(service, "action_url");
358 }
359
360 Value ServicesTable::ActionUrlExpandedAccessor(const Value& row)
361 {
362         Service::Ptr service = static_cast<Service::Ptr>(row);
363
364         if (!service)
365                 return Empty;
366
367         MacroProcessor::ResolverList resolvers;
368         resolvers.push_back(std::make_pair("service", service));
369         resolvers.push_back(std::make_pair("host", service->GetHost()));
370         resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
371
372         Value value = CompatUtility::GetCustomAttributeConfig(service, "action_url");
373
374         return MacroProcessor::ResolveMacros(value, resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd);
375 }
376
377 Value ServicesTable::IconImageAccessor(const Value& row)
378 {
379         Service::Ptr service = static_cast<Service::Ptr>(row);
380
381         if (!service)
382                 return Empty;
383
384         return CompatUtility::GetCustomAttributeConfig(service, "icon_image");
385 }
386
387 Value ServicesTable::IconImageExpandedAccessor(const Value& row)
388 {
389         Service::Ptr service = static_cast<Service::Ptr>(row);
390
391         if (!service)
392                 return Empty;
393
394         MacroProcessor::ResolverList resolvers;
395         resolvers.push_back(std::make_pair("service", service));
396         resolvers.push_back(std::make_pair("host", service->GetHost()));
397         resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
398
399         Value value = CompatUtility::GetCustomAttributeConfig(service, "icon_image");
400
401         return MacroProcessor::ResolveMacros(value, resolvers, CheckResult::Ptr(), Utility::EscapeShellCmd);
402 }
403
404 Value ServicesTable::IconImageAltAccessor(const Value& row)
405 {
406         Service::Ptr service = static_cast<Service::Ptr>(row);
407
408         if (!service)
409                 return Empty;
410
411         return CompatUtility::GetCustomAttributeConfig(service, "icon_image_alt");
412 }
413
414 Value ServicesTable::MaxCheckAttemptsAccessor(const Value& row)
415 {
416         Service::Ptr service = static_cast<Service::Ptr>(row);
417
418         if (!service)
419                 return Empty;
420
421         return service->GetMaxCheckAttempts();
422 }
423
424 Value ServicesTable::CurrentAttemptAccessor(const Value& row)
425 {
426         Service::Ptr service = static_cast<Service::Ptr>(row);
427
428         if (!service)
429                 return Empty;
430
431         return service->GetCheckAttempt();
432 }
433
434 Value ServicesTable::StateAccessor(const Value& row)
435 {
436         Service::Ptr service = static_cast<Service::Ptr>(row);
437
438         if (!service)
439                 return Empty;
440
441         return service->GetState();
442 }
443
444 Value ServicesTable::HasBeenCheckedAccessor(const Value& row)
445 {
446         Service::Ptr service = static_cast<Service::Ptr>(row);
447
448         if (!service)
449                 return Empty;
450
451         return CompatUtility::GetCheckableHasBeenChecked(service);
452 }
453
454 Value ServicesTable::LastStateAccessor(const Value& row)
455 {
456         Service::Ptr service = static_cast<Service::Ptr>(row);
457
458         if (!service)
459                 return Empty;
460
461         return service->GetLastState();
462 }
463
464 Value ServicesTable::LastHardStateAccessor(const Value& row)
465 {
466         Service::Ptr service = static_cast<Service::Ptr>(row);
467
468         if (!service)
469                 return Empty;
470
471         return service->GetLastHardState();
472 }
473
474 Value ServicesTable::StateTypeAccessor(const Value& row)
475 {
476         Service::Ptr service = static_cast<Service::Ptr>(row);
477
478         if (!service)
479                 return Empty;
480
481         return service->GetStateType();
482 }
483
484 Value ServicesTable::CheckTypeAccessor(const Value& row)
485 {
486         Service::Ptr service = static_cast<Service::Ptr>(row);
487
488         if (!service)
489                 return Empty;
490
491         return CompatUtility::GetCheckableCheckType(service);
492 }
493
494 Value ServicesTable::AcknowledgedAccessor(const Value& row)
495 {
496         Service::Ptr service = static_cast<Service::Ptr>(row);
497
498         if (!service)
499                 return Empty;
500
501
502         return CompatUtility::GetCheckableIsAcknowledged(service);
503 }
504
505 Value ServicesTable::AcknowledgementTypeAccessor(const Value& row)
506 {
507         Service::Ptr service = static_cast<Service::Ptr>(row);
508
509         if (!service)
510                 return Empty;
511
512         /* important: lock acknowledgements */
513         ObjectLock olock(service);
514
515         return static_cast<int>(service->GetAcknowledgement());
516 }
517
518 Value ServicesTable::NoMoreNotificationsAccessor(const Value& row)
519 {
520         Service::Ptr service = static_cast<Service::Ptr>(row);
521
522         if (!service)
523                 return Empty;
524
525         return CompatUtility::GetCheckableNoMoreNotifications(service);
526 }
527
528 Value ServicesTable::LastTimeOkAccessor(const Value& row)
529 {
530         Service::Ptr service = static_cast<Service::Ptr>(row);
531
532         if (!service)
533                 return Empty;
534
535         return static_cast<int>(service->GetLastStateOK());
536 }
537
538 Value ServicesTable::LastTimeWarningAccessor(const Value& row)
539 {
540         Service::Ptr service = static_cast<Service::Ptr>(row);
541
542         if (!service)
543                 return Empty;
544
545         return static_cast<int>(service->GetLastStateWarning());
546 }
547
548 Value ServicesTable::LastTimeCriticalAccessor(const Value& row)
549 {
550         Service::Ptr service = static_cast<Service::Ptr>(row);
551
552         if (!service)
553                 return Empty;
554
555         return static_cast<int>(service->GetLastStateCritical());
556 }
557
558 Value ServicesTable::LastTimeUnknownAccessor(const Value& row)
559 {
560         Service::Ptr service = static_cast<Service::Ptr>(row);
561
562         if (!service)
563                 return Empty;
564
565         return static_cast<int>(service->GetLastStateUnknown());
566 }
567
568 Value ServicesTable::LastCheckAccessor(const Value& row)
569 {
570         Service::Ptr service = static_cast<Service::Ptr>(row);
571
572         if (!service)
573                 return Empty;
574
575         return static_cast<int>(service->GetLastCheck());
576 }
577
578 Value ServicesTable::NextCheckAccessor(const Value& row)
579 {
580         Service::Ptr service = static_cast<Service::Ptr>(row);
581
582         if (!service)
583                 return Empty;
584
585         return static_cast<int>(service->GetNextCheck());
586 }
587
588 Value ServicesTable::LastNotificationAccessor(const Value& row)
589 {
590         Service::Ptr service = static_cast<Service::Ptr>(row);
591
592         if (!service)
593                 return Empty;
594
595         return CompatUtility::GetCheckableNotificationLastNotification(service);
596 }
597
598 Value ServicesTable::NextNotificationAccessor(const Value& row)
599 {
600         Service::Ptr service = static_cast<Service::Ptr>(row);
601
602         if (!service)
603                 return Empty;
604
605         return CompatUtility::GetCheckableNotificationNextNotification(service);
606 }
607
608 Value ServicesTable::CurrentNotificationNumberAccessor(const Value& row)
609 {
610         Service::Ptr service = static_cast<Service::Ptr>(row);
611
612         if (!service)
613                 return Empty;
614
615         return CompatUtility::GetCheckableNotificationNotificationNumber(service);
616 }
617
618 Value ServicesTable::LastStateChangeAccessor(const Value& row)
619 {
620         Service::Ptr service = static_cast<Service::Ptr>(row);
621
622         if (!service)
623                 return Empty;
624
625         return static_cast<int>(service->GetLastStateChange());
626 }
627
628 Value ServicesTable::LastHardStateChangeAccessor(const Value& row)
629 {
630         Service::Ptr service = static_cast<Service::Ptr>(row);
631
632         if (!service)
633                 return Empty;
634
635         return static_cast<int>(service->GetLastHardStateChange());
636 }
637
638 Value ServicesTable::ScheduledDowntimeDepthAccessor(const Value& row)
639 {
640         Service::Ptr service = static_cast<Service::Ptr>(row);
641
642         if (!service)
643                 return Empty;
644
645         return service->GetDowntimeDepth();
646 }
647
648 Value ServicesTable::IsFlappingAccessor(const Value& row)
649 {
650         Service::Ptr service = static_cast<Service::Ptr>(row);
651
652         if (!service)
653                 return Empty;
654
655         return service->IsFlapping();
656 }
657
658 Value ServicesTable::ChecksEnabledAccessor(const Value& row)
659 {
660         Service::Ptr service = static_cast<Service::Ptr>(row);
661
662         if (!service)
663                 return Empty;
664
665         return CompatUtility::GetCheckableActiveChecksEnabled(service);
666 }
667
668 Value ServicesTable::AcceptPassiveChecksAccessor(const Value& row)
669 {
670         Service::Ptr service = static_cast<Service::Ptr>(row);
671
672         if (!service)
673                 return Empty;
674
675         return CompatUtility::GetCheckablePassiveChecksEnabled(service);
676 }
677
678 Value ServicesTable::EventHandlerEnabledAccessor(const Value& row)
679 {
680         Service::Ptr service = static_cast<Service::Ptr>(row);
681
682         if (!service)
683                 return Empty;
684
685         return CompatUtility::GetCheckableEventHandlerEnabled(service);
686 }
687
688 Value ServicesTable::NotificationsEnabledAccessor(const Value& row)
689 {
690         Service::Ptr service = static_cast<Service::Ptr>(row);
691
692         if (!service)
693                 return Empty;
694
695         return CompatUtility::GetCheckableNotificationsEnabled(service);
696 }
697
698 Value ServicesTable::ProcessPerformanceDataAccessor(const Value& row)
699 {
700         Service::Ptr service = static_cast<Service::Ptr>(row);
701
702         if (!service)
703                 return Empty;
704
705         return  CompatUtility::GetCheckableProcessPerformanceData(service);
706 }
707
708 Value ServicesTable::ActiveChecksEnabledAccessor(const Value& row)
709 {
710         Service::Ptr service = static_cast<Service::Ptr>(row);
711
712         if (!service)
713                 return Empty;
714
715         return CompatUtility::GetCheckableActiveChecksEnabled(service);
716 }
717
718 Value ServicesTable::CheckOptionsAccessor(const Value& row)
719 {
720         /* TODO - forcexec, freshness, orphan, none */
721         return Empty;
722 }
723
724 Value ServicesTable::FlapDetectionEnabledAccessor(const Value& row)
725 {
726         Service::Ptr service = static_cast<Service::Ptr>(row);
727
728         if (!service)
729                 return Empty;
730
731         return CompatUtility::GetCheckableFlapDetectionEnabled(service);
732 }
733
734 Value ServicesTable::CheckFreshnessAccessor(const Value& row)
735 {
736         Service::Ptr service = static_cast<Service::Ptr>(row);
737
738         if (!service)
739                 return Empty;
740
741         return CompatUtility::GetCheckableFreshnessChecksEnabled(service);
742 }
743
744 Value ServicesTable::ModifiedAttributesAccessor(const Value& row)
745 {
746         Service::Ptr service = static_cast<Service::Ptr>(row);
747
748         if (!service)
749                 return Empty;
750
751         return service->GetModifiedAttributes();
752 }
753
754 Value ServicesTable::ModifiedAttributesListAccessor(const Value& row)
755 {
756         /* not supported */
757         return Empty;
758 }
759
760 Value ServicesTable::StalenessAccessor(const Value& row)
761 {
762         Service::Ptr service = static_cast<Service::Ptr>(row);
763
764         if (!service)
765                 return Empty;
766
767         return CompatUtility::GetCheckableStaleness(service);
768 }
769
770 Value ServicesTable::CheckIntervalAccessor(const Value& row)
771 {
772         Service::Ptr service = static_cast<Service::Ptr>(row);
773
774         if (!service)
775                 return Empty;
776
777         return CompatUtility::GetCheckableCheckInterval(service);
778 }
779
780 Value ServicesTable::RetryIntervalAccessor(const Value& row)
781 {
782         Service::Ptr service = static_cast<Service::Ptr>(row);
783
784         if (!service)
785                 return Empty;
786
787         return CompatUtility::GetCheckableRetryInterval(service);
788 }
789
790 Value ServicesTable::NotificationIntervalAccessor(const Value& row)
791 {
792         Service::Ptr service = static_cast<Service::Ptr>(row);
793
794         if (!service)
795                 return Empty;
796
797         return CompatUtility::GetCheckableNotificationNotificationInterval(service);
798 }
799
800 Value ServicesTable::LowFlapThresholdAccessor(const Value& row)
801 {
802         Service::Ptr service = static_cast<Service::Ptr>(row);
803
804         if (!service)
805                 return Empty;
806
807         return CompatUtility::GetCheckableLowFlapThreshold(service);
808 }
809
810 Value ServicesTable::HighFlapThresholdAccessor(const Value& row)
811 {
812         Service::Ptr service = static_cast<Service::Ptr>(row);
813
814         if (!service)
815                 return Empty;
816
817         return CompatUtility::GetCheckableHighFlapThreshold(service);
818 }
819
820 Value ServicesTable::LatencyAccessor(const Value& row)
821 {
822         Service::Ptr service = static_cast<Service::Ptr>(row);
823
824         if (!service)
825                 return Empty;
826
827         return (Service::CalculateLatency(service->GetLastCheckResult()));
828 }
829
830 Value ServicesTable::ExecutionTimeAccessor(const Value& row)
831 {
832         Service::Ptr service = static_cast<Service::Ptr>(row);
833
834         if (!service)
835                 return Empty;
836
837         return (Service::CalculateExecutionTime(service->GetLastCheckResult()));
838 }
839
840 Value ServicesTable::PercentStateChangeAccessor(const Value& row)
841 {
842         Service::Ptr service = static_cast<Service::Ptr>(row);
843
844         if (!service)
845                 return Empty;
846
847         return CompatUtility::GetCheckablePercentStateChange(service);
848 }
849
850 Value ServicesTable::InCheckPeriodAccessor(const Value& row)
851 {
852         Service::Ptr service = static_cast<Service::Ptr>(row);
853
854         if (!service)
855                 return Empty;
856
857         return CompatUtility::GetCheckableInCheckPeriod(service);
858 }
859
860 Value ServicesTable::InNotificationPeriodAccessor(const Value& row)
861 {
862         Service::Ptr service = static_cast<Service::Ptr>(row);
863
864         if (!service)
865                 return Empty;
866
867         return CompatUtility::GetCheckableInNotificationPeriod(service);
868 }
869
870 Value ServicesTable::ContactsAccessor(const Value& row)
871 {
872         Service::Ptr service = static_cast<Service::Ptr>(row);
873
874         if (!service)
875                 return Empty;
876
877         Array::Ptr contact_names = make_shared<Array>();
878
879         BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(service)) {
880                 contact_names->Add(user->GetName());
881         }
882
883         return contact_names;
884 }
885
886 Value ServicesTable::DowntimesAccessor(const Value& row)
887 {
888         Service::Ptr service = static_cast<Service::Ptr>(row);
889
890         if (!service)
891                 return Empty;
892
893         Dictionary::Ptr downtimes = service->GetDowntimes();
894
895         Array::Ptr ids = make_shared<Array>();
896
897         ObjectLock olock(downtimes);
898
899         String id;
900         Downtime::Ptr downtime;
901         BOOST_FOREACH(tie(id, downtime), downtimes) {
902
903                 if (!downtime)
904                         continue;
905
906                 if (downtime->IsExpired())
907                         continue;
908
909                 ids->Add(downtime->GetLegacyId());
910         }
911
912         return ids;
913 }
914
915 Value ServicesTable::DowntimesWithInfoAccessor(const Value& row)
916 {
917         Service::Ptr service = static_cast<Service::Ptr>(row);
918
919         if (!service)
920                 return Empty;
921
922         Dictionary::Ptr downtimes = service->GetDowntimes();
923
924         Array::Ptr ids = make_shared<Array>();
925
926         ObjectLock olock(downtimes);
927
928         String id;
929         Downtime::Ptr downtime;
930         BOOST_FOREACH(tie(id, downtime), downtimes) {
931
932                 if (!downtime)
933                         continue;
934
935                 if (downtime->IsExpired())
936                         continue;
937
938                 Array::Ptr downtime_info = make_shared<Array>();
939                 downtime_info->Add(downtime->GetLegacyId());
940                 downtime_info->Add(downtime->GetAuthor());
941                 downtime_info->Add(downtime->GetComment());
942                 ids->Add(downtime_info);
943         }
944
945         return ids;
946 }
947
948 Value ServicesTable::CommentsAccessor(const Value& row)
949 {
950         Service::Ptr service = static_cast<Service::Ptr>(row);
951
952         if (!service)
953                 return Empty;
954
955         Dictionary::Ptr comments = service->GetComments();
956
957         Array::Ptr ids = make_shared<Array>();
958
959         ObjectLock olock(comments);
960
961         String id;
962         Comment::Ptr comment;
963         BOOST_FOREACH(tie(id, comment), comments) {
964
965                 if (!comment)
966                         continue;
967
968                 if (comment->IsExpired())
969                         continue;
970
971                 ids->Add(comment->GetLegacyId());
972         }
973
974         return ids;
975 }
976
977 Value ServicesTable::CommentsWithInfoAccessor(const Value& row)
978 {
979         Service::Ptr service = static_cast<Service::Ptr>(row);
980
981         if (!service)
982                 return Empty;
983
984         Dictionary::Ptr comments = service->GetComments();
985
986         Array::Ptr ids = make_shared<Array>();
987
988         ObjectLock olock(comments);
989
990         String id;
991         Comment::Ptr comment;
992         BOOST_FOREACH(tie(id, comment), comments) {
993
994                 if (!comment)
995                         continue;
996
997                 if (comment->IsExpired())
998                         continue;
999
1000                 Array::Ptr comment_info = make_shared<Array>();
1001                 comment_info->Add(comment->GetLegacyId());
1002                 comment_info->Add(comment->GetAuthor());
1003                 comment_info->Add(comment->GetText());
1004                 ids->Add(comment_info);
1005         }
1006
1007         return ids;
1008 }
1009
1010 Value ServicesTable::CommentsWithExtraInfoAccessor(const Value& row)
1011 {
1012         Service::Ptr service = static_cast<Service::Ptr>(row);
1013
1014         if (!service)
1015                 return Empty;
1016
1017         Dictionary::Ptr comments = service->GetComments();
1018
1019         Array::Ptr ids = make_shared<Array>();
1020
1021         ObjectLock olock(comments);
1022
1023         String id;
1024         Comment::Ptr comment;
1025         BOOST_FOREACH(tie(id, comment), comments) {
1026
1027                 if (!comment)
1028                         continue;
1029
1030                 if (comment->IsExpired())
1031                         continue;
1032
1033                 Array::Ptr comment_info = make_shared<Array>();
1034                 comment_info->Add(comment->GetLegacyId());
1035                 comment_info->Add(comment->GetAuthor());
1036                 comment_info->Add(comment->GetText());
1037                 comment_info->Add(comment->GetEntryType());
1038                 comment_info->Add(static_cast<int>(comment->GetEntryTime()));
1039                 ids->Add(comment_info);
1040         }
1041
1042         return ids;
1043 }
1044
1045 Value ServicesTable::CustomVariableNamesAccessor(const Value& row)
1046 {
1047         Service::Ptr service = static_cast<Service::Ptr>(row);
1048
1049         if (!service)
1050                 return Empty;
1051
1052         Dictionary::Ptr vars;
1053
1054         {
1055                 ObjectLock olock(service);
1056                 vars = CompatUtility::GetCustomAttributeConfig(service);
1057         }
1058
1059         if (!vars)
1060                 return Empty;
1061
1062         Array::Ptr cv = make_shared<Array>();
1063
1064         String key;
1065         Value value;
1066         BOOST_FOREACH(tie(key, value), vars) {
1067                 cv->Add(key);
1068         }
1069
1070         return cv;
1071 }
1072
1073 Value ServicesTable::CustomVariableValuesAccessor(const Value& row)
1074 {
1075         Service::Ptr service = static_cast<Service::Ptr>(row);
1076
1077         if (!service)
1078                 return Empty;
1079
1080         Dictionary::Ptr vars;
1081
1082         {
1083                 ObjectLock olock(service);
1084                 vars = CompatUtility::GetCustomAttributeConfig(service);
1085         }
1086
1087         if (!vars)
1088                 return Empty;
1089
1090         Array::Ptr cv = make_shared<Array>();
1091
1092         String key;
1093         Value value;
1094         BOOST_FOREACH(tie(key, value), vars) {
1095                 cv->Add(value);
1096         }
1097
1098         return cv;
1099 }
1100
1101 Value ServicesTable::CustomVariablesAccessor(const Value& row)
1102 {
1103         Service::Ptr service = static_cast<Service::Ptr>(row);
1104
1105         if (!service)
1106                 return Empty;
1107
1108         Dictionary::Ptr vars;
1109
1110         {
1111                 ObjectLock olock(service);
1112                 vars = CompatUtility::GetCustomAttributeConfig(service);
1113         }
1114
1115         if (!vars)
1116                 return Empty;
1117
1118         Array::Ptr cv = make_shared<Array>();
1119
1120         String key;
1121         Value value;
1122         BOOST_FOREACH(tie(key, value), vars) {
1123                 Array::Ptr key_val = make_shared<Array>();
1124                 key_val->Add(key);
1125                 key_val->Add(value);
1126                 cv->Add(key_val);
1127         }
1128
1129         return cv;
1130 }
1131
1132 Value ServicesTable::GroupsAccessor(const Value& row)
1133 {
1134         Service::Ptr service = static_cast<Service::Ptr>(row);
1135
1136         if (!service)
1137                 return Empty;
1138
1139         Array::Ptr groups = service->GetGroups();
1140
1141         if (!groups)
1142                 return Empty;
1143
1144         return groups;
1145 }
1146
1147 Value ServicesTable::ContactGroupsAccessor(const Value& row)
1148 {
1149         Service::Ptr service = static_cast<Service::Ptr>(row);
1150
1151         if (!service)
1152                 return Empty;
1153
1154         Array::Ptr contactgroup_names = make_shared<Array>();
1155
1156         BOOST_FOREACH(const UserGroup::Ptr& usergroup, CompatUtility::GetCheckableNotificationUserGroups(service)) {
1157                 contactgroup_names->Add(usergroup->GetName());
1158         }
1159
1160         return contactgroup_names;
1161 }
1162
1163 Value ServicesTable::CheckSourceAccessor(const Value& row)
1164 {
1165         Service::Ptr service = static_cast<Service::Ptr>(row);
1166
1167         if (!service)
1168                 return Empty;
1169
1170         CheckResult::Ptr cr = service->GetLastCheckResult();
1171
1172         if (cr)
1173                 return cr->GetCheckSource();
1174
1175         return Empty;
1176 }
1177
1178