NotificationQuery: Use subqueries to fetch host- and service-notifications

refs #9009
This commit is contained in:
Johannes Meyer 2015-06-08 17:09:24 +02:00
parent 70e3434f33
commit 9229e460d1
2 changed files with 143 additions and 107 deletions

View File

@ -3,136 +3,127 @@
namespace Icinga\Module\Monitoring\Backend\Ido\Query; namespace Icinga\Module\Monitoring\Backend\Ido\Query;
use Zend_Db_Expr;
use Zend_Db_Select;
use Icinga\Data\Filter\Filter;
/**
* Query for host and service notifications
*/
class NotificationQuery extends IdoQuery class NotificationQuery extends IdoQuery
{ {
/**
* {@inheritdoc}
*/
protected $columnMap = array( protected $columnMap = array(
'notification' => array( 'notifications' => array(
'notification_output' => 'n.output', 'notification_state' => 'n.notification_state',
'notification_start_time' => 'UNIX_TIMESTAMP(n.start_time)', 'notification_start_time' => 'n.notification_start_time',
'notification_state' => 'n.state', 'notification_contact_name' => 'n.notification_contact_name',
'notification_object_id' => 'n.object_id' 'notification_output' => 'n.notification_output',
), 'notification_object_id' => 'n.notification_object_id',
'objects' => array( 'contact_object_id' => 'n.contact_object_id',
'host' => 'o.name1 COLLATE latin1_general_ci', 'acknowledgement_entry_time' => 'n.acknowledgement_entry_time',
'host_name' => 'o.name1', 'acknowledgement_author_name' => 'n.acknowledgement_author_name',
'service' => 'o.name2 COLLATE latin1_general_ci', 'acknowledgement_comment_data' => 'n.acknowledgement_comment_data',
'service_description' => 'o.name2' 'object_type' => 'n.object_type'
),
'contact' => array(
'contact' => 'c_o.name1 COLLATE latin1_general_ci',
'notification_contact_name' => 'c_o.name1',
'contact_object_id' => 'c_o.object_id'
),
'command' => array(
'notification_command' => 'cmd_o.name1'
),
'acknowledgement' => array(
'acknowledgement_entry_time' => 'UNIX_TIMESTAMP(a.entry_time)',
'acknowledgement_author_name' => 'a.author_name',
'acknowledgement_comment_data' => 'a.comment_data'
), ),
'hosts' => array( 'hosts' => array(
'host_display_name' => 'CASE WHEN sh.display_name IS NOT NULL THEN sh.display_name ELSE h.display_name END' 'host_display_name' => 'n.host_display_name',
'host_name' => 'n.host_name'
), ),
'services' => array( 'services' => array(
'service_display_name' => 's.display_name' 'service_description' => 'n.service_description',
'service_display_name' => 'n.service_display_name',
'service_host_name' => 'n.service_host_name'
) )
); );
/** /**
* Fetch basic information about notifications * The union
*
* @var Zend_Db_Select
*/
protected $notificationQuery;
/**
* Subqueries used for the notification query
*
* @var IdoQuery[]
*/
protected $subQueries = array();
/**
* {@inheritdoc}
*/ */
protected function joinBaseTables() protected function joinBaseTables()
{ {
$this->notificationQuery = $this->db->select();
$this->select->from( $this->select->from(
array('n' => $this->prefix . 'notifications'), array('n' => $this->notificationQuery),
array() array()
); );
$this->joinedVirtualTables = array('notification' => true); $this->joinedVirtualTables['notifications'] = true;
} }
/** /**
* Fetch description of each affected host/service * Join hosts
*/ */
protected function joinObjects()
{
$this->select->join(
array('o' => $this->prefix . 'objects'),
'n.object_id = o.object_id AND o.is_active = 1 AND o.objecttype_id IN (1, 2)',
array()
);
}
/**
* Fetch name of involved contacts and/or contact groups
*/
protected function joinContact()
{
$this->select->join(
array('c' => $this->prefix . 'contactnotifications'),
'n.notification_id = c.notification_id',
array()
);
$this->select->join(
array('c_o' => $this->prefix . 'objects'),
'c.contact_object_id = c_o.object_id',
array()
);
}
/**
* Fetch name of the command which was used to send out a notification
*/
protected function joinCommand()
{
$this->select->join(
array('cmd_c' => $this->prefix . 'contactnotifications'),
'n.notification_id = cmd_c.notification_id',
array()
);
$this->select->joinLeft(
array('cmd_m' => $this->prefix . 'contactnotificationmethods'),
'cmd_c.contactnotification_id = cmd_m.contactnotification_id',
array()
);
$this->select->joinLeft(
array('cmd_o' => $this->prefix . 'objects'),
'cmd_m.command_object_id = cmd_o.object_id',
array()
);
}
protected function joinAcknowledgement()
{
$this->select->joinLeft(
array('a' => $this->prefix . 'acknowledgements'),
'n.object_id = a.object_id',
array()
);
}
protected function joinHosts() protected function joinHosts()
{ {
$this->select->joinLeft( $columns = array_keys($this->columnMap['notifications'] + $this->columnMap['hosts']);
array('h' => $this->prefix . 'hosts'), foreach (array_keys($this->columnMap['services']) as $column) {
'h.host_object_id = o.object_id', $columns[$column] = new Zend_Db_Expr('NULL');
array() }
$hosts = $this->createSubQuery('hostnotification', $columns);
$this->subQueries[] = $hosts;
$this->notificationQuery->union(array($hosts), Zend_Db_Select::SQL_UNION_ALL);
}
/**
* Join services
*/
protected function joinServices()
{
$columns = array_keys(
$this->columnMap['notifications'] + $this->columnMap['hosts'] + $this->columnMap['services']
); );
$services = $this->createSubQuery('servicenotification', $columns);
$this->subQueries[] = $services;
$this->notificationQuery->union(array($services), Zend_Db_Select::SQL_UNION_ALL);
}
/**
* {@inheritdoc}
*/
public function order($columnOrAlias, $dir = null)
{
foreach ($this->subQueries as $sub) {
$sub->requireColumn($columnOrAlias);
}
return parent::order($columnOrAlias, $dir);
}
/**
* {@inheritdoc}
*/
public function where($condition, $value = null)
{
$this->requireColumn($condition);
foreach ($this->subQueries as $sub) {
$sub->where($condition, $value);
}
return $this; return $this;
} }
protected function joinServices() /**
* {@inheritdoc}
*/
public function addFilter(Filter $filter)
{ {
$this->select->joinLeft( foreach ($this->subQueries as $sub) {
array('s' => $this->prefix . 'services'), $sub->applyFilter(clone $filter);
's.service_object_id = o.object_id', }
array()
);
$this->select->joinLeft(
array('sh' => $this->prefix . 'hosts'),
'sh.host_object_id = s.host_object_id',
array()
);
return $this; return $this;
} }
} }

View File

@ -5,6 +5,19 @@ namespace Icinga\Module\Monitoring\DataView;
class Notification extends DataView class Notification extends DataView
{ {
/**
* {@inheritdoc}
*/
public function isValidFilterTarget($column)
{
if ($column[0] === '_'
&& preg_match('/^_(?:host|service)_/', $column)
) {
return true;
}
return parent::isValidFilterTarget($column);
}
/** /**
* Retrieve columns provided by this view * Retrieve columns provided by this view
* *
@ -13,30 +26,62 @@ class Notification extends DataView
public function getColumns() public function getColumns()
{ {
return array( return array(
'host_name',
'service_description',
'notification_state', 'notification_state',
'notification_start_time', 'notification_start_time',
'notification_contact_name', 'notification_contact_name',
'notification_output', 'notification_output',
'notification_command', 'notification_object_id',
'contact_object_id',
'acknowledgement_entry_time',
'acknowledgement_author_name',
'acknowledgement_comment_data',
'host_display_name', 'host_display_name',
'service_display_name' 'host_name',
'object_type',
'service_description',
'service_display_name',
'service_host_name'
); );
} }
/**
* {@inheritdoc}
*/
public function getSortRules() public function getSortRules()
{ {
return array( return array(
'notification_start_time' => array( 'notification_start_time' => array(
'order' => self::SORT_DESC, 'order' => self::SORT_DESC,
'title' => 'Notification Start' 'title' => 'Notification Start'
),
'host_display_name' => array(
'columns' => array(
'host_display_name',
'service_display_name'
),
'order' => self::SORT_ASC
),
'service_display_name' => array(
'columns' => array(
'service_display_name',
'host_display_name'
),
'order' => self::SORT_ASC
) )
); );
} }
/**
* {@inheritdoc}
*/
public function getFilterColumns() public function getFilterColumns()
{ {
return array('host', 'service', 'contact'); return array(
'contact',
'host', 'host_alias',
'hostgroup', 'hostgroup_alias', 'hostgroup_name',
'service',
'servicegroup', 'servicegroup_alias', 'servicegroup_name'
);
} }
} }