From 51a3213fcaa06d6c1d86c2a68a4769b349282ae0 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 10 Jun 2015 13:10:28 +0200 Subject: [PATCH] NotificationQuery: Add support for history related queries refs #9009 --- .../Ido/Query/HostnotificationQuery.php | 54 +++++++++++++++++-- .../Backend/Ido/Query/NotificationQuery.php | 31 +++++++++++ .../Ido/Query/ServicenotificationQuery.php | 52 +++++++++++++++++- 3 files changed, 132 insertions(+), 5 deletions(-) diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php index 86930e12e..631f5974b 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php @@ -26,6 +26,13 @@ class HostnotificationQuery extends IdoQuery 'host_name' => 'ho.name1', 'object_type' => '(\'host\')' ), + 'history' => array( + 'type' => "('notify')", + 'timestamp' => 'UNIX_TIMESTAMP(hn.start_time)', + 'object_id' => 'hn.object_id', + 'state' => 'hn.state', + 'output' => null + ), 'contactnotifications' => array( 'contact' => 'cno.name1 COLLATE latin1_general_ci', 'notification_contact_name' => 'cno.name1', @@ -63,6 +70,31 @@ class HostnotificationQuery extends IdoQuery */ protected function joinBaseTables() { + switch ($this->ds->getDbType()) { + case 'mysql': + $concattedContacts = "GROUP_CONCAT(" + . "cno.name1 ORDER BY cno.name1 SEPARATOR ', '" + . ") COLLATE latin1_general_ci"; + break; + case 'pgsql': + // TODO: Find a way to order the contact alias list: + $concattedContacts = "ARRAY_TO_STRING(ARRAY_AGG(cno.name1), ', ')"; + break; + case 'oracle': + // TODO: This is only valid for Oracle >= 11g Release 2 + $concattedContacts = "LISTAGG(cno.name1, ', ') WITHIN GROUP (ORDER BY cno.name1)"; + // Alternatives: + // + // RTRIM(XMLAGG(XMLELEMENT(e, column_name, ',').EXTRACT('//text()')), + // + // not supported and not documented but works since 10.1, + // however it is NOT always present: + // WM_CONCAT(c.alias) + break; + } + + $this->columnMap['history']['output'] = "('[' || $concattedContacts || '] ' || hn.output)"; + $this->select->from( array('hn' => $this->prefix . 'notifications'), array() @@ -80,6 +112,15 @@ class HostnotificationQuery extends IdoQuery $this->joinedVirtualTables['notifications'] = true; } + /** + * Join virtual table history + */ + protected function joinHistory() + { + $this->requireVirtualTable('contactnotifications'); + $this->group(array('hn.notification_id', 'ho.name1')); + } + /** * Join contact notifications */ @@ -95,6 +136,7 @@ class HostnotificationQuery extends IdoQuery 'cno.object_id = cn.contact_object_id', array() ); + $this->group(array('cn.contactnotification_id', 'ho.name1')); } /** @@ -134,7 +176,10 @@ class HostnotificationQuery extends IdoQuery 'hgo.objecttype_id = ?', 3 ); - $this->group(array('hn.notification_id', 'ho.name1')); + + if (! $this->hasJoinedVirtualTable('contactnotifications')) { + $this->group(array('hn.notification_id', 'ho.name1')); + } } /** @@ -184,7 +229,7 @@ class HostnotificationQuery extends IdoQuery { $this->select->join( array('s' => $this->prefix . 'services'), - 's.host_object_id = h.host_object_id', + 's.host_object_id = ho.object_id', array() )->join( array('so' => $this->prefix . 'objects'), @@ -198,6 +243,9 @@ class HostnotificationQuery extends IdoQuery 'so.objecttype_id = ?', 2 ); - $this->group(array('hn.notification_id', 'ho.name1')); + + if (! $this->hasJoinedVirtualTable('contactnotifications')) { + $this->group(array('hn.notification_id', 'ho.name1')); + } } } diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationQuery.php index f898c8699..135875d07 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/NotificationQuery.php @@ -27,6 +27,13 @@ class NotificationQuery extends IdoQuery 'acknowledgement_comment_data' => 'n.acknowledgement_comment_data', 'object_type' => 'n.object_type' ), + 'history' => array( + 'type' => 'n.type', + 'timestamp' => 'n.timestamp', + 'object_id' => 'n.object_id', + 'state' => 'n.state', + 'output' => 'n.output' + ), 'hosts' => array( 'host_display_name' => 'n.host_display_name', 'host_name' => 'n.host_name' @@ -52,6 +59,13 @@ class NotificationQuery extends IdoQuery */ protected $subQueries = array(); + /** + * Whether to additionally select all history columns + * + * @var bool + */ + protected $fetchHistoryColumns = false; + /** * {@inheritdoc} */ @@ -65,6 +79,17 @@ class NotificationQuery extends IdoQuery $this->joinedVirtualTables['notifications'] = true; } + /** + * Join history related columns and tables + */ + protected function joinHistory() + { + // TODO: Ensure that one is selecting the history columns first... + $this->fetchHistoryColumns = true; + $this->requireVirtualTable('hosts'); + $this->requireVirtualTable('services'); + } + /** * Join hosts */ @@ -73,6 +98,9 @@ class NotificationQuery extends IdoQuery $columns = array_keys( $this->columnMap['notifications'] + $this->columnMap['hosts'] + $this->columnMap['services'] ); + if ($this->fetchHistoryColumns) { + $columns = array_merge($columns, array_keys($this->columnMap['history'])); + } $hosts = $this->createSubQuery('hostnotification', $columns); $this->subQueries[] = $hosts; $this->notificationQuery->union(array($hosts), Zend_Db_Select::SQL_UNION_ALL); @@ -86,6 +114,9 @@ class NotificationQuery extends IdoQuery $columns = array_keys( $this->columnMap['notifications'] + $this->columnMap['hosts'] + $this->columnMap['services'] ); + if ($this->fetchHistoryColumns) { + $columns = array_merge($columns, array_keys($this->columnMap['history'])); + } $services = $this->createSubQuery('servicenotification', $columns); $this->subQueries[] = $services; $this->notificationQuery->union(array($services), Zend_Db_Select::SQL_UNION_ALL); diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php index aaf3d57bc..3341a6e61 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php @@ -30,6 +30,13 @@ class ServicenotificationQuery extends IdoQuery 'service_host' => 'so.name1 COLLATE latin1_general_ci', 'service_host_name' => 'so.name1' ), + 'history' => array( + 'type' => "('notify')", + 'timestamp' => 'UNIX_TIMESTAMP(sn.start_time)', + 'object_id' => 'sn.object_id', + 'state' => 'sn.state', + 'output' => null + ), 'contactnotifications' => array( 'contact' => 'cno.name1 COLLATE latin1_general_ci', 'notification_contact_name' => 'cno.name1', @@ -64,6 +71,31 @@ class ServicenotificationQuery extends IdoQuery */ protected function joinBaseTables() { + switch ($this->ds->getDbType()) { + case 'mysql': + $concattedContacts = "GROUP_CONCAT(" + . "cno.name1 ORDER BY cno.name1 SEPARATOR ', '" + . ") COLLATE latin1_general_ci"; + break; + case 'pgsql': + // TODO: Find a way to order the contact alias list: + $concattedContacts = "ARRAY_TO_STRING(ARRAY_AGG(cno.name1), ', ')"; + break; + case 'oracle': + // TODO: This is only valid for Oracle >= 11g Release 2 + $concattedContacts = "LISTAGG(cno.name1, ', ') WITHIN GROUP (ORDER BY cno.name1)"; + // Alternatives: + // + // RTRIM(XMLAGG(XMLELEMENT(e, column_name, ',').EXTRACT('//text()')), + // + // not supported and not documented but works since 10.1, + // however it is NOT always present: + // WM_CONCAT(c.alias) + break; + } + + $this->columnMap['history']['output'] = "('[' || $concattedContacts || '] ' || sn.output)"; + $this->select->from( array('sn' => $this->prefix . 'notifications'), array() @@ -81,6 +113,15 @@ class ServicenotificationQuery extends IdoQuery $this->joinedVirtualTables['notifications'] = true; } + /** + * Join virtual table history + */ + protected function joinHistory() + { + $this->requireVirtualTable('contactnotifications'); + $this->group(array('sn.notification_id', 'so.name2', 'so.name1')); + } + /** * Join contact notifications */ @@ -96,6 +137,7 @@ class ServicenotificationQuery extends IdoQuery 'cno.object_id = cn.contact_object_id', array() ); + $this->group(array('cn.contactnotification_id', 'so.name2', 'so.name1')); } /** @@ -136,7 +178,6 @@ class ServicenotificationQuery extends IdoQuery 'hgo.objecttype_id = ?', 3 ); - $this->group(array('sn.notification_id', 'so.name2', 'so.name1')); } /** @@ -177,7 +218,10 @@ class ServicenotificationQuery extends IdoQuery 'sgo.objecttype_id = ?', 4 ); - $this->group(array('sn.notification_id', 'so.name2', 'so.name1')); + + if (! $this->hasJoinedVirtualTable('contactnotifications')) { + $this->group(array('sn.notification_id', 'so.name2', 'so.name1')); + } } /** @@ -190,5 +234,9 @@ class ServicenotificationQuery extends IdoQuery 's.service_object_id = so.object_id', array() ); + + if (! $this->hasJoinedVirtualTable('contactnotifications')) { + $this->group(array('sn.notification_id', 'so.name2', 'so.name1')); + } } }