From ab6bf66ef2c5b33229c615bc8cd0be148227ded6 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Thu, 28 Jul 2016 20:37:22 +0000 Subject: [PATCH 01/20] Update tracker to version 2.0.4 --- modules/tracker/configs/module.ini | 2 +- modules/tracker/database/mysql/2.0.4.sql | 159 +++++++++++++++++++++ modules/tracker/database/upgrade/2.0.4.php | 37 +++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 modules/tracker/database/mysql/2.0.4.sql create mode 100644 modules/tracker/database/upgrade/2.0.4.php diff --git a/modules/tracker/configs/module.ini b/modules/tracker/configs/module.ini index e47190b71..f07b8bff7 100644 --- a/modules/tracker/configs/module.ini +++ b/modules/tracker/configs/module.ini @@ -6,4 +6,4 @@ description = "Track scalar results over time" category = "Visualization" dependencies = api,scheduler uuid = "3048a9fa-89ab-4e61-a55e-a49379fa6dc" -version = "2.0.3" +version = "2.0.4" diff --git a/modules/tracker/database/mysql/2.0.4.sql b/modules/tracker/database/mysql/2.0.4.sql new file mode 100644 index 000000000..389707694 --- /dev/null +++ b/modules/tracker/database/mysql/2.0.4.sql @@ -0,0 +1,159 @@ +-- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. + +-- MySQL database for the tracker module, version 2.0.4 + +CREATE TABLE IF NOT EXISTS `tracker_producer` ( + `producer_id` bigint(20) NOT NULL AUTO_INCREMENT, + `community_id` bigint(20) NOT NULL, + `repository` varchar(255) NOT NULL, + `executable_name` varchar(255) NOT NULL, + `display_name` varchar(255) NOT NULL, + `description` text NOT NULL, + `revision_url` text NOT NULL, + `histogram_max_x` double, + `producer_definition` text, + PRIMARY KEY (`producer_id`), + KEY (`community_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_scalar` ( + `scalar_id` bigint(20) NOT NULL AUTO_INCREMENT, + `trend_id` bigint(20) NOT NULL, + `value` double, + `submission_id` bigint(20) NOT NULL, + PRIMARY KEY (`scalar_id`), + KEY (`trend_id`), + KEY (`submission_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_submission` ( + `submission_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `uuid` varchar(255) NOT NULL DEFAULT '', + `submit_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `producer_revision` varchar(255), + `user_id` bigint(20) NOT NULL DEFAULT '-1', + `official` tinyint(4) NOT NULL DEFAULT '1', + `build_results_url` text NOT NULL, + `branch` varchar(255) NOT NULL DEFAULT '', + `extra_urls` text, + `reproduction_command` text, + PRIMARY KEY (`submission_id`), + UNIQUE KEY (`uuid`), + KEY (`user_id`), + KEY (`submit_time`), + KEY (`branch`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_submission2item` ( + `submission_id` bigint(20) NOT NULL, + `item_id` bigint(20) NOT NULL, + `label` varchar(255) NOT NULL, + `trendgroup_id` bigint(20) NOT NULL, + KEY (`submission_id`), + KEY (`item_id`), + KEY (`trendgroup_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_threshold_notification` ( + `threshold_id` bigint(20) NOT NULL AUTO_INCREMENT, + `trend_id` bigint(20) NOT NULL, + `value` double, + `comparison` varchar(2), + `action` varchar(80) NOT NULL, + `recipient_id` bigint(20) NOT NULL, + PRIMARY KEY (`threshold_id`), + KEY (`trend_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_trend` ( + `trend_id` bigint(20) NOT NULL AUTO_INCREMENT, + `trendgroup_id` bigint(20), + `metric_name` varchar(255) NOT NULL, + `display_name` varchar(255) NOT NULL, + `unit` varchar(255) NOT NULL, + `key_metric` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`trend_id`), + KEY (`trendgroup_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_trend_threshold` ( + `trend_threshold_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `metric_name` varchar(255) NOT NULL, + `abbreviation` varchar(255) NOT NULL DEFAULT '', + `warning` double, + `fail` double, + `min` double, + `max` double, + `lower_is_better` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`trend_threshold_id`), + KEY (`producer_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_trendgroup` ( + `trendgroup_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `config_item_id` bigint(20), + `test_dataset_id` bigint(20), + `truth_dataset_id` bigint(20), + PRIMARY KEY (`trendgroup_id`), + KEY (`producer_id`), + KEY (`config_item_id`), + KEY (`test_dataset_id`), + KEY (`truth_dataset_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_param` ( + `param_id` bigint(20) NOT NULL AUTO_INCREMENT, + `submission_id` bigint(20) NOT NULL, + `param_name` varchar(255) NOT NULL, + `param_type` enum('text', 'numeric') NOT NULL, + `text_value` text, + `numeric_value` double, + PRIMARY KEY (`param_id`), + KEY (`submission_id`), + KEY (`param_name`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric` ( + `aggregate_metric_id` bigint(20) NOT NULL AUTO_INCREMENT, + `aggregate_metric_spec_id` bigint(20) NOT NULL, + `submission_id` bigint(20) NOT NULL, + `value` double, + PRIMARY KEY (`aggregate_metric_id`), + KEY (`aggregate_metric_spec_id`), + KEY (`submission_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric_spec` ( + `aggregate_metric_spec_id` bigint(20) NOT NULL AUTO_INCREMENT, + `producer_id` bigint(20) NOT NULL, + `name` varchar(255) NOT NULL DEFAULT '', + `description` varchar(255) NOT NULL DEFAULT '', + `spec` text NOT NULL DEFAULT '', + `abbreviation` varchar(255) NOT NULL DEFAULT '', + `warning` double, + `fail` double, + `max` double, + PRIMARY KEY (`aggregate_metric_spec_id`), + KEY (`producer_id`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric_notification` ( + `aggregate_metric_notification_id` bigint(20) NOT NULL AUTO_INCREMENT, + `aggregate_metric_spec_id` bigint(20) NOT NULL, + `branch` varchar(255) NOT NULL DEFAULT '', + `value` double, + `comparison` varchar(2) NOT NULL DEFAULT '', + PRIMARY KEY (`aggregate_metric_notification_id`), + KEY (`aggregate_metric_spec_id`), + KEY (`branch`) +) DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `tracker_user2aggregate_metric_notification` ( + `user_id` bigint(20) NOT NULL, + `aggregate_metric_notification_id` bigint(20) NOT NULL, + PRIMARY KEY (`user_id`, `aggregate_metric_notification_id`) +) DEFAULT CHARSET=utf8; diff --git a/modules/tracker/database/upgrade/2.0.4.php b/modules/tracker/database/upgrade/2.0.4.php new file mode 100644 index 000000000..64ae040bd --- /dev/null +++ b/modules/tracker/database/upgrade/2.0.4.php @@ -0,0 +1,37 @@ +db->query( + 'ALTER TABLE `tracker_producer` '. + ' ADD COLUMN `producer_definition` text;' + ); + $this->db->query( + 'ALTER TABLE `tracker_trend_threshold` '. + ' ADD COLUMN `min` double,'. + ' ADD COLUMN `lower_is_better` tinyint(4) NOT NULL DEFAULT 0;' + ); + } +} From a04f752484b76fcd39980304161d09620951548d Mon Sep 17 00:00:00 2001 From: mgrauer Date: Thu, 28 Jul 2016 20:37:45 +0000 Subject: [PATCH 02/20] Correct tracker db script version number comments --- modules/tracker/database/mysql/2.0.2.sql | 2 +- modules/tracker/database/mysql/2.0.3.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/tracker/database/mysql/2.0.2.sql b/modules/tracker/database/mysql/2.0.2.sql index 9f41cb05d..c78792409 100644 --- a/modules/tracker/database/mysql/2.0.2.sql +++ b/modules/tracker/database/mysql/2.0.2.sql @@ -1,6 +1,6 @@ -- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. --- MySQL database for the tracker module, version 2.0.1 +-- MySQL database for the tracker module, version 2.0.2 CREATE TABLE IF NOT EXISTS `tracker_producer` ( `producer_id` bigint(20) NOT NULL AUTO_INCREMENT, diff --git a/modules/tracker/database/mysql/2.0.3.sql b/modules/tracker/database/mysql/2.0.3.sql index 4b62b26c1..93538a026 100644 --- a/modules/tracker/database/mysql/2.0.3.sql +++ b/modules/tracker/database/mysql/2.0.3.sql @@ -1,6 +1,6 @@ -- Midas Server. Copyright Kitware SAS. Licensed under the Apache License 2.0. --- MySQL database for the tracker module, version 2.0.1 +-- MySQL database for the tracker module, version 2.0.3 CREATE TABLE IF NOT EXISTS `tracker_producer` ( `producer_id` bigint(20) NOT NULL AUTO_INCREMENT, From 4ab2214d60fd826076a5965b45e4672be0f7fdc3 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Thu, 28 Jul 2016 20:39:22 +0000 Subject: [PATCH 03/20] Add producer_definition to Tracker Producer model --- modules/tracker/models/base/ProducerModelBase.php | 1 + modules/tracker/models/dao/ProducerDao.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/modules/tracker/models/base/ProducerModelBase.php b/modules/tracker/models/base/ProducerModelBase.php index e1345562c..322013252 100644 --- a/modules/tracker/models/base/ProducerModelBase.php +++ b/modules/tracker/models/base/ProducerModelBase.php @@ -37,6 +37,7 @@ public function __construct() 'display_name' => array('type' => MIDAS_DATA), 'description' => array('type' => MIDAS_DATA), 'histogram_max_x' => array('type' => MIDAS_DATA), + 'producer_definition' => array('type' => MIDAS_DATA), 'community' => array( 'type' => MIDAS_MANY_TO_ONE, 'model' => 'Community', diff --git a/modules/tracker/models/dao/ProducerDao.php b/modules/tracker/models/dao/ProducerDao.php index 547662dc1..490d608e2 100644 --- a/modules/tracker/models/dao/ProducerDao.php +++ b/modules/tracker/models/dao/ProducerDao.php @@ -39,6 +39,8 @@ * @method void setCommunity(CommunityDao $communityDao) * @method array getTrendgroups() * @method void setTrendgroups(array $trendgroupDaos) + * @method string getProducerDefinition() + * @method void setProducerDefinition(string $producerDefinition) */ class Tracker_ProducerDao extends Tracker_AppDao { From 16a6552568358e439a41f02d5f6b0a078ac1741d Mon Sep 17 00:00:00 2001 From: mgrauer Date: Thu, 28 Jul 2016 20:41:06 +0000 Subject: [PATCH 04/20] Add setAggregatableTrendAsKeyMetrics to Tracker Trend model --- .../tracker/models/base/TrendModelBase.php | 9 ++++++++ modules/tracker/models/pdo/TrendModel.php | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/modules/tracker/models/base/TrendModelBase.php b/modules/tracker/models/base/TrendModelBase.php index 0a25df14a..717280afa 100644 --- a/modules/tracker/models/base/TrendModelBase.php +++ b/modules/tracker/models/base/TrendModelBase.php @@ -96,6 +96,15 @@ abstract public function getScalars($trendDao, $startDate = null, $endDate = nul */ abstract public function getTrendsByGroup($producerDao, $onlyKey = false); + /** + * Set all Trends with the passed in metric_name to key_metrics, + * for the passed in Producer. + * + * @param Tracker_ProducerDao $producerDao producer DAO + * @param string $metricName The metric_name to match against trends + */ + abstract public function setAggregatableTrendAsKeyMetrics($producerDao, $metricName); + /** * Save the given trend. Ensure that null values are explicitly set in the database. * diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index 782dc874c..027f9c304 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -151,6 +151,27 @@ public function getTrendsByGroup($producerDao, $onlyKey = false) return $results; } + /** + * Set all Trends with the passed in metric_name to key_metrics, + * for the passed in Producer. + * + * @param Tracker_ProducerDao $producerDao producer DAO + * @param string $metricName The metric_name to match against trends + */ + public function setAggregatableTrendAsKeyMetrics($producerDao, $metricName) + { + if (is_null($producerDao) || $producerDao === false) { + return false; + } + $producerIdQ = $this->database->getDB()->quote($producerDao->getProducerId()); + $metricNameQ = $this->database->getDB()->quote($metricName); + $update = 'UPDATE tracker_trend, tracker_trendgroup SET key_metric=1 WHERE'. + ' producer_id = ' . $producerIdQ . + ' AND tracker_trend.trendgroup_id = tracker_trendgroup.trendgroup_id '. + ' AND tracker_trend.metric_name = ' . $metricNameQ; + $this->database->getDB()->query($update); + } + /** * Return the trend DAOs that match the given associative array of database columns and values. * From d19e25b8f05cba8a539b904fea9672b1a3cf0b6a Mon Sep 17 00:00:00 2001 From: mgrauer Date: Thu, 28 Jul 2016 20:48:29 +0000 Subject: [PATCH 05/20] Add upsert to Tracker TrendThreshold model --- .../models/base/TrendThresholdModelBase.php | 25 +++++++++ .../tracker/models/dao/TrendThresholdDao.php | 4 ++ .../models/pdo/TrendThresholdModel.php | 56 +++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/modules/tracker/models/base/TrendThresholdModelBase.php b/modules/tracker/models/base/TrendThresholdModelBase.php index 01e469b56..0f6814cb2 100644 --- a/modules/tracker/models/base/TrendThresholdModelBase.php +++ b/modules/tracker/models/base/TrendThresholdModelBase.php @@ -36,7 +36,9 @@ public function __construct() 'abbreviation' => array('type' => MIDAS_DATA), 'warning' => array('type' => MIDAS_DATA), 'fail' => array('type' => MIDAS_DATA), + 'min' => array('type' => MIDAS_DATA), 'max' => array('type' => MIDAS_DATA), + 'lower_is_better' => array('type' => MIDAS_DATA), 'producer' => array( 'type' => MIDAS_MANY_TO_ONE, 'model' => 'Producer', @@ -48,4 +50,27 @@ public function __construct() $this->initialize(); } + + /** + * Create or update a Tracker TrendThreshold tied to the Producer and metric_name. + * + * @param Tracker_ProducerDao $producerDao + * @param string $metricName metric name of the trend threshold + * @param false|string $abbreviation name abbreviation for the threshold + * @param false|float $warning warning value for this threshold + * @param false|float $fail fail value for this threshold + * @param false|float $min min value for display of this threshold + * @param false|float $max max value for display of this threshold + * @param false|boolean $lowerIsBetter whether lower values are better for this threshold + * @return Tracker_TrendThresholdDao updated or created DAO + */ + abstract public function upsert( + $producerDao, + $metricName, + $abbreviation = false, + $warning = false, + $fail = false, + $min = false, + $max = false, + $lowerIsBetter = false); } diff --git a/modules/tracker/models/dao/TrendThresholdDao.php b/modules/tracker/models/dao/TrendThresholdDao.php index ea3c1acd5..a4b3c338c 100644 --- a/modules/tracker/models/dao/TrendThresholdDao.php +++ b/modules/tracker/models/dao/TrendThresholdDao.php @@ -33,8 +33,12 @@ * @method void setWarning(float $warning) * @method float getFail() * @method void setFail(float $fail) + * @method float getMin() + * @method void setMin(float $min) * @method float getMax() * @method void setMax(float $max) + * @method boolean getLowerIsBetter() + * @method void setLowerIsBetter(boolean $lowerIsBetter) * @method Tracker_ProducerDao getProducer() * @method void setProducer(Tracker_ProducerDao $producerDao) */ diff --git a/modules/tracker/models/pdo/TrendThresholdModel.php b/modules/tracker/models/pdo/TrendThresholdModel.php index fa73438d7..7959b60cb 100644 --- a/modules/tracker/models/pdo/TrendThresholdModel.php +++ b/modules/tracker/models/pdo/TrendThresholdModel.php @@ -23,4 +23,60 @@ /** Trend Threshold model for the tracker module. */ class Tracker_TrendThresholdModel extends Tracker_TrendThresholdModelBase { + /** + * Create or update a Tracker TrendThreshold tied to the Producer and metric_name. + * + * @param Tracker_ProducerDao $producerDao + * @param string $metricName metric name of the trend threshold + * @param false|string $abbreviation name abbreviation for the threshold + * @param false|float $warning warning value for this threshold + * @param false|float $fail fail value for this threshold + * @param false|float $min min value for display of this threshold + * @param false|float $max max value for display of this threshold + * @param false|boolean $lowerIsBetter whether lower values are better for this threshold + * @return Tracker_TrendThresholdDao updated or created DAO + */ + public function upsert( + $producerDao, + $metricName, + $abbreviation = false, + $warning = false, + $fail = false, + $min = false, + $max = false, + $lowerIsBetter = false) + { + if (is_null($producerDao) || $producerDao === false) { + return false; + } + $sql = $this->database->select()->setIntegrityCheck(false) + ->where('producer_id = ?', $producerDao->getProducerId()) + ->where('metric_name = ?', $metricName); + /** @var Tracker_TrendThresholdDao $trendThresholdDao */ + $trendThresholdDao = $this->initDao('TrendThreshold', $this->database->fetchRow($sql), $this->moduleName); + if ($trendThresholdDao === false) { + $trendThresholdDao = MidasLoader::newDao('TrendThresholdDao', $this->moduleName); + } + if ($abbreviation !== false) { + $trendThresholdDao->setAbbreviation($abbreviation); + } + if ($warning !== false) { + $trendThresholdDao->setWarning($warning); + } + if ($fail !== false) { + $trendThresholdDao->setFail($fail); + } + if ($min !== false) { + $trendThresholdDao->setMin($min); + } + if ($max !== false) { + $trendThresholdDao->setMax($max); + } + if ($lowerIsBetter !== false) { + $trendThresholdDao->setLowerIsBetter($lowerIsBetter); + } + $this->save($trendThresholdDao); + + return $trendThresholdDao; + } } From a2cec163a10e50d93571d4b836987a5d5a323ad7 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Thu, 28 Jul 2016 21:20:30 +0000 Subject: [PATCH 06/20] Update producer definition based on producer schema --- .../controllers/components/ApiComponent.php | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 8d9defd40..eead42969 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -341,6 +341,7 @@ public function submissionAdd($args) * @param uuid The uuid of the submission to validate documents for * @param producerConfig (Optional) JSON object describing the pipeline * @param submissionDocument (Optional) JSON object describing the submission + * @throws Exception */ public function submissionValidate($args) { @@ -370,11 +371,66 @@ public function submissionValidate($args) if (!$validator->isValid()) { $this->getLogger()->warn('The supplied producerConfig JSON for uuid '.$uuid." does not validate. Violations:\n"); + /** @var array $error */ foreach ($validator->getErrors() as $error) { $this->getLogger()->warn(sprintf("[%s] %s\n", $error['property'], $error['message'])); } } else { $this->getLogger()->info('The supplied producerConfig JSON for uuid '.$uuid.' is valid.'); + + /** @var Tracker_ProducerModel $producerModel */ + $producerModel = MidasLoader::loadModel('Producer', 'tracker'); + /** @var Tracker_ProducerDao $producerDao */ + $producerDao = $submissionDao->getProducer(); + if (!$producerModel->policyCheck( + $producerDao, + $user, + MIDAS_POLICY_WRITE + )) { + throw new Exception('Write permission on the producer required', 403); + } + /** @var stdClass $producerDefinition */ + $producerDefinition = json_decode($producerConfig); + // Ensure that Producer and Community match. + if ($producerDefinition->producer !== $producerDao->getDisplayName()) { + throw new Exception('Producer schema name must match existing Producer display name', 404); + } + if ($producerDefinition->community !== $producerDao->getCommunity()->getName()) { + throw new Exception('Producer schema community name must match existing Producer Community name', 404); + } + + // Save the producer definition to the producer. + $producerDao->setProducerDefinition($producerConfig); + $producerModel->save($producerDao); + + $defaults = $producerDefinition->defaults; + if (!isset($defaults)) { + // Provide a default for $defaults so the below ?: logic works. + $defaults = new stdClass(); + } + $keyMetrics = $producerDefinition->key_metrics; + /** @var stdClass $keyMetric */ + foreach($keyMetrics as $keyMetric) { + /** @var Tracker_TrendModel $trendModel */ + $trendModel = MidasLoader::loadModel('Trend', 'tracker'); + // Set any needed trends to be key_metrics. + $trendModel->setAggregatableTrendAsKeyMetrics($producerDao, $keyMetric->name); + /** @var Tracker_TrendThresholdModel $trendThresholdModel */ + $trendThresholdModel = MidasLoader::loadModel('TrendThreshold', 'tracker'); + $trendThresholdModel->upsert($producerDao, $keyMetric->name, + isset($keyMetric->abbreviation) ? $keyMetric->abbreviation : false, + isset($keyMetric->warning) ? $keyMetric->warning : + (isset($defaults->warning) ? $defaults->warning : false), + isset($keyMetric->fail) ? $keyMetric->fail : + (isset($defaults->fail) ? $defaults->fail : false), + isset($keyMetric->min) ? $keyMetric->min : + (isset($defaults->min) ? $defaults->min : false), + isset($keyMetric->max) ? $keyMetric->max : + (isset($defaults->max) ? $defaults->max : false), + isset($keyMetric->lower_is_better) ? $keyMetric->lower_is_better : + (isset($defaults->lower_is_better) ? $defaults->lower_is_better : false) + ); + } } } From 2c2915516d1db01e3342f64d480327c810fad562 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Thu, 28 Jul 2016 17:26:49 -0400 Subject: [PATCH 07/20] Applied fixes from StyleCI --- .../controllers/components/ApiComponent.php | 2 +- .../models/base/TrendThresholdModelBase.php | 26 +++--- .../tracker/models/dao/TrendThresholdDao.php | 2 +- modules/tracker/models/pdo/TrendModel.php | 4 +- .../models/pdo/TrendThresholdModel.php | 82 +++++++++---------- 5 files changed, 58 insertions(+), 58 deletions(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index eead42969..41c6e66e0 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -410,7 +410,7 @@ public function submissionValidate($args) } $keyMetrics = $producerDefinition->key_metrics; /** @var stdClass $keyMetric */ - foreach($keyMetrics as $keyMetric) { + foreach ($keyMetrics as $keyMetric) { /** @var Tracker_TrendModel $trendModel */ $trendModel = MidasLoader::loadModel('Trend', 'tracker'); // Set any needed trends to be key_metrics. diff --git a/modules/tracker/models/base/TrendThresholdModelBase.php b/modules/tracker/models/base/TrendThresholdModelBase.php index 0f6814cb2..bc75738b3 100644 --- a/modules/tracker/models/base/TrendThresholdModelBase.php +++ b/modules/tracker/models/base/TrendThresholdModelBase.php @@ -51,19 +51,19 @@ public function __construct() $this->initialize(); } - /** - * Create or update a Tracker TrendThreshold tied to the Producer and metric_name. - * - * @param Tracker_ProducerDao $producerDao - * @param string $metricName metric name of the trend threshold - * @param false|string $abbreviation name abbreviation for the threshold - * @param false|float $warning warning value for this threshold - * @param false|float $fail fail value for this threshold - * @param false|float $min min value for display of this threshold - * @param false|float $max max value for display of this threshold - * @param false|boolean $lowerIsBetter whether lower values are better for this threshold - * @return Tracker_TrendThresholdDao updated or created DAO - */ + /** + * Create or update a Tracker TrendThreshold tied to the Producer and metric_name. + * + * @param Tracker_ProducerDao $producerDao + * @param string $metricName metric name of the trend threshold + * @param false|string $abbreviation name abbreviation for the threshold + * @param false|float $warning warning value for this threshold + * @param false|float $fail fail value for this threshold + * @param false|float $min min value for display of this threshold + * @param false|float $max max value for display of this threshold + * @param false|bool $lowerIsBetter whether lower values are better for this threshold + * @return Tracker_TrendThresholdDao updated or created DAO + */ abstract public function upsert( $producerDao, $metricName, diff --git a/modules/tracker/models/dao/TrendThresholdDao.php b/modules/tracker/models/dao/TrendThresholdDao.php index a4b3c338c..c7a3d42c9 100644 --- a/modules/tracker/models/dao/TrendThresholdDao.php +++ b/modules/tracker/models/dao/TrendThresholdDao.php @@ -37,7 +37,7 @@ * @method void setMin(float $min) * @method float getMax() * @method void setMax(float $max) - * @method boolean getLowerIsBetter() + * @method bool getLowerIsBetter() * @method void setLowerIsBetter(boolean $lowerIsBetter) * @method Tracker_ProducerDao getProducer() * @method void setProducer(Tracker_ProducerDao $producerDao) diff --git a/modules/tracker/models/pdo/TrendModel.php b/modules/tracker/models/pdo/TrendModel.php index 027f9c304..e7ce0d95f 100644 --- a/modules/tracker/models/pdo/TrendModel.php +++ b/modules/tracker/models/pdo/TrendModel.php @@ -166,9 +166,9 @@ public function setAggregatableTrendAsKeyMetrics($producerDao, $metricName) $producerIdQ = $this->database->getDB()->quote($producerDao->getProducerId()); $metricNameQ = $this->database->getDB()->quote($metricName); $update = 'UPDATE tracker_trend, tracker_trendgroup SET key_metric=1 WHERE'. - ' producer_id = ' . $producerIdQ . + ' producer_id = '.$producerIdQ. ' AND tracker_trend.trendgroup_id = tracker_trendgroup.trendgroup_id '. - ' AND tracker_trend.metric_name = ' . $metricNameQ; + ' AND tracker_trend.metric_name = '.$metricNameQ; $this->database->getDB()->query($update); } diff --git a/modules/tracker/models/pdo/TrendThresholdModel.php b/modules/tracker/models/pdo/TrendThresholdModel.php index 7959b60cb..d8e668234 100644 --- a/modules/tracker/models/pdo/TrendThresholdModel.php +++ b/modules/tracker/models/pdo/TrendThresholdModel.php @@ -24,18 +24,18 @@ class Tracker_TrendThresholdModel extends Tracker_TrendThresholdModelBase { /** - * Create or update a Tracker TrendThreshold tied to the Producer and metric_name. - * - * @param Tracker_ProducerDao $producerDao - * @param string $metricName metric name of the trend threshold - * @param false|string $abbreviation name abbreviation for the threshold - * @param false|float $warning warning value for this threshold - * @param false|float $fail fail value for this threshold - * @param false|float $min min value for display of this threshold - * @param false|float $max max value for display of this threshold - * @param false|boolean $lowerIsBetter whether lower values are better for this threshold - * @return Tracker_TrendThresholdDao updated or created DAO - */ + * Create or update a Tracker TrendThreshold tied to the Producer and metric_name. + * + * @param Tracker_ProducerDao $producerDao + * @param string $metricName metric name of the trend threshold + * @param false|string $abbreviation name abbreviation for the threshold + * @param false|float $warning warning value for this threshold + * @param false|float $fail fail value for this threshold + * @param false|float $min min value for display of this threshold + * @param false|float $max max value for display of this threshold + * @param false|bool $lowerIsBetter whether lower values are better for this threshold + * @return Tracker_TrendThresholdDao updated or created DAO + */ public function upsert( $producerDao, $metricName, @@ -45,38 +45,38 @@ public function upsert( $min = false, $max = false, $lowerIsBetter = false) - { - if (is_null($producerDao) || $producerDao === false) { - return false; - } - $sql = $this->database->select()->setIntegrityCheck(false) + { + if (is_null($producerDao) || $producerDao === false) { + return false; + } + $sql = $this->database->select()->setIntegrityCheck(false) ->where('producer_id = ?', $producerDao->getProducerId()) ->where('metric_name = ?', $metricName); /** @var Tracker_TrendThresholdDao $trendThresholdDao */ $trendThresholdDao = $this->initDao('TrendThreshold', $this->database->fetchRow($sql), $this->moduleName); - if ($trendThresholdDao === false) { - $trendThresholdDao = MidasLoader::newDao('TrendThresholdDao', $this->moduleName); - } - if ($abbreviation !== false) { - $trendThresholdDao->setAbbreviation($abbreviation); - } - if ($warning !== false) { - $trendThresholdDao->setWarning($warning); - } - if ($fail !== false) { - $trendThresholdDao->setFail($fail); - } - if ($min !== false) { - $trendThresholdDao->setMin($min); - } - if ($max !== false) { - $trendThresholdDao->setMax($max); - } - if ($lowerIsBetter !== false) { - $trendThresholdDao->setLowerIsBetter($lowerIsBetter); - } - $this->save($trendThresholdDao); + if ($trendThresholdDao === false) { + $trendThresholdDao = MidasLoader::newDao('TrendThresholdDao', $this->moduleName); + } + if ($abbreviation !== false) { + $trendThresholdDao->setAbbreviation($abbreviation); + } + if ($warning !== false) { + $trendThresholdDao->setWarning($warning); + } + if ($fail !== false) { + $trendThresholdDao->setFail($fail); + } + if ($min !== false) { + $trendThresholdDao->setMin($min); + } + if ($max !== false) { + $trendThresholdDao->setMax($max); + } + if ($lowerIsBetter !== false) { + $trendThresholdDao->setLowerIsBetter($lowerIsBetter); + } + $this->save($trendThresholdDao); - return $trendThresholdDao; - } + return $trendThresholdDao; + } } From 766b5e204014f065524decb22ee37ee9277ff28d Mon Sep 17 00:00:00 2001 From: mgrauer Date: Sun, 31 Jul 2016 20:17:10 +0000 Subject: [PATCH 08/20] Add fields to producer definition --- modules/tracker/database/mysql/2.0.4.sql | 2 ++ modules/tracker/database/upgrade/2.0.4.php | 2 ++ modules/tracker/models/base/ProducerModelBase.php | 9 +++++++++ modules/tracker/models/dao/ProducerDao.php | 8 ++++++++ 4 files changed, 21 insertions(+) diff --git a/modules/tracker/database/mysql/2.0.4.sql b/modules/tracker/database/mysql/2.0.4.sql index 389707694..2ac28096c 100644 --- a/modules/tracker/database/mysql/2.0.4.sql +++ b/modules/tracker/database/mysql/2.0.4.sql @@ -11,6 +11,8 @@ CREATE TABLE IF NOT EXISTS `tracker_producer` ( `description` text NOT NULL, `revision_url` text NOT NULL, `histogram_max_x` double, + `grid_across_metric_groups` tinyint(4) NOT NULL DEFAULT '0', + `histogram_number_of_bins` int(11) NOT NULL DEFAULT '10', `producer_definition` text, PRIMARY KEY (`producer_id`), KEY (`community_id`) diff --git a/modules/tracker/database/upgrade/2.0.4.php b/modules/tracker/database/upgrade/2.0.4.php index 64ae040bd..16211dfff 100644 --- a/modules/tracker/database/upgrade/2.0.4.php +++ b/modules/tracker/database/upgrade/2.0.4.php @@ -26,6 +26,8 @@ public function mysql() { $this->db->query( 'ALTER TABLE `tracker_producer` '. + ' ADD COLUMN `grid_across_metric_groups` tinyint(4) NOT NULL DEFAULT 0,'. + ' ADD COLUMN `histogram_number_of_bins` int(11) NOT NULL DEFAULT 10,'. ' ADD COLUMN `producer_definition` text;' ); $this->db->query( diff --git a/modules/tracker/models/base/ProducerModelBase.php b/modules/tracker/models/base/ProducerModelBase.php index 322013252..56e6d6827 100644 --- a/modules/tracker/models/base/ProducerModelBase.php +++ b/modules/tracker/models/base/ProducerModelBase.php @@ -37,6 +37,8 @@ public function __construct() 'display_name' => array('type' => MIDAS_DATA), 'description' => array('type' => MIDAS_DATA), 'histogram_max_x' => array('type' => MIDAS_DATA), + 'grid_across_metric_groups' => array('type' => MIDAS_DATA), + 'histogram_number_of_bins' => array('type' => MIDAS_DATA), 'producer_definition' => array('type' => MIDAS_DATA), 'community' => array( 'type' => MIDAS_MANY_TO_ONE, @@ -51,6 +53,13 @@ public function __construct() 'parent_column' => 'producer_id', 'child_column' => 'producer_id', ), + 'trendthresholds' => array( + 'type' => MIDAS_ONE_TO_MANY, + 'model' => 'TrendThreshold', + 'module' => $this->moduleName, + 'parent_column' => 'producer_id', + 'child_column' => 'producer_id', + ), ); $this->initialize(); diff --git a/modules/tracker/models/dao/ProducerDao.php b/modules/tracker/models/dao/ProducerDao.php index 490d608e2..24e2e075d 100644 --- a/modules/tracker/models/dao/ProducerDao.php +++ b/modules/tracker/models/dao/ProducerDao.php @@ -39,6 +39,14 @@ * @method void setCommunity(CommunityDao $communityDao) * @method array getTrendgroups() * @method void setTrendgroups(array $trendgroupDaos) + * @method array getTrendthresholds() + * @method void setTrendthresholds(array $trendthresholdDaos) + * @method void setHistogramMaxX(float $histogramMaxX) + * @method float getHistogramMaxX() + * @method bool getGridAcrossMetricGroups() + * @method void setGridAcrossMetricGroups(boolean $gridAcrossMetricGroups) + * @method int getHistogramNumberOfBins() + * @method void setHistogramNumberOfBins(int $histogramNumberOfBins) * @method string getProducerDefinition() * @method void setProducerDefinition(string $producerDefinition) */ From 83faecd89ed75d4beed8513f1a936364849a457a Mon Sep 17 00:00:00 2001 From: mgrauer Date: Sun, 31 Jul 2016 20:18:26 +0000 Subject: [PATCH 09/20] Set producer level fields from producer definition --- .../tracker/controllers/components/ApiComponent.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 41c6e66e0..b91499136 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -358,9 +358,6 @@ public function submissionValidate($args) } if (isset($args['producerConfig'])) { - // At the current time, we are looking for the producerConfig, - // validating it, and logging a warning with any violations, we - // are not saving the producerConfig. $producerConfig = $args['producerConfig']; $refResolver = new JsonSchema\RefResolver(new JsonSchema\Uri\UriRetriever(), new JsonSchema\Uri\UriResolver()); $schemaPath = BASE_PATH.'/modules/tracker/schema/producer.json'; @@ -401,6 +398,16 @@ public function submissionValidate($args) // Save the producer definition to the producer. $producerDao->setProducerDefinition($producerConfig); + // Update top level fields on the producer based on the definition. + if (isset($producerDefinition->histogram_max_x)) { + $producerDao->setHistogramMaxX($producerDefinition->histogram_max_x); + } + if (isset($producerDefinition->grid_across_metric_groups)) { + $producerDao->setGridAcrossMetricGroups($producerDefinition->grid_across_metric_groups); + } + if (isset($producerDefinition->histogram_number_of_bins)) { + $producerDao->setHistogramNumberOfBins($producerDefinition->histogram_number_of_bins); + } $producerModel->save($producerDao); $defaults = $producerDefinition->defaults; From 7bccc72983fa3ce90eef1320abb0df54c93ca9dd Mon Sep 17 00:00:00 2001 From: mgrauer Date: Sun, 31 Jul 2016 20:20:20 +0000 Subject: [PATCH 10/20] Add document to submission model --- modules/tracker/database/mysql/2.0.4.sql | 1 + modules/tracker/database/upgrade/2.0.4.php | 4 ++++ modules/tracker/models/base/SubmissionModelBase.php | 1 + modules/tracker/models/dao/SubmissionDao.php | 2 ++ 4 files changed, 8 insertions(+) diff --git a/modules/tracker/database/mysql/2.0.4.sql b/modules/tracker/database/mysql/2.0.4.sql index 2ac28096c..3eb8d9f45 100644 --- a/modules/tracker/database/mysql/2.0.4.sql +++ b/modules/tracker/database/mysql/2.0.4.sql @@ -41,6 +41,7 @@ CREATE TABLE IF NOT EXISTS `tracker_submission` ( `branch` varchar(255) NOT NULL DEFAULT '', `extra_urls` text, `reproduction_command` text, + `document` text, PRIMARY KEY (`submission_id`), UNIQUE KEY (`uuid`), KEY (`user_id`), diff --git a/modules/tracker/database/upgrade/2.0.4.php b/modules/tracker/database/upgrade/2.0.4.php index 16211dfff..e95506f6f 100644 --- a/modules/tracker/database/upgrade/2.0.4.php +++ b/modules/tracker/database/upgrade/2.0.4.php @@ -35,5 +35,9 @@ public function mysql() ' ADD COLUMN `min` double,'. ' ADD COLUMN `lower_is_better` tinyint(4) NOT NULL DEFAULT 0;' ); + $this->db->query( + 'ALTER TABLE `tracker_submission` '. + ' ADD COLUMN `document` text;' + ); } } diff --git a/modules/tracker/models/base/SubmissionModelBase.php b/modules/tracker/models/base/SubmissionModelBase.php index 755a1d2e8..f87217369 100644 --- a/modules/tracker/models/base/SubmissionModelBase.php +++ b/modules/tracker/models/base/SubmissionModelBase.php @@ -42,6 +42,7 @@ public function __construct() 'extra_urls' => array('type' => MIDAS_DATA), 'branch' => array('type' => MIDAS_DATA), 'producer_revision' => array('type' => MIDAS_DATA), + 'document' => array('type' => MIDAS_DATA), 'reproduction_command' => array('type' => MIDAS_DATA), 'producer' => array( 'type' => MIDAS_MANY_TO_ONE, diff --git a/modules/tracker/models/dao/SubmissionDao.php b/modules/tracker/models/dao/SubmissionDao.php index 9f0c61983..e99158e1a 100644 --- a/modules/tracker/models/dao/SubmissionDao.php +++ b/modules/tracker/models/dao/SubmissionDao.php @@ -49,6 +49,8 @@ * @method void setProducerRevision(string $producerRevision) * @method string getReproductionCommand() * @method void setReproductionCommand(string $reproductionCommand) + * @method string getDocument() + * @method void setDocument(string $document) */ class Tracker_SubmissionDao extends Tracker_AppDao { From a11b9914fd0e564d394c9e050cec061555ed540b Mon Sep 17 00:00:00 2001 From: mgrauer Date: Sun, 31 Jul 2016 20:20:40 +0000 Subject: [PATCH 11/20] Save document to submission model in API --- .../controllers/components/ApiComponent.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index b91499136..77ec8e378 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -442,9 +442,6 @@ public function submissionValidate($args) } if (isset($args['submissionDocument'])) { - // At the current time, we are looking for the submissionDocument, - // validating it, and logging a warning with any violations, we - // are not saving the producerConfig. $submissionDocument = $args['submissionDocument']; $refResolver = new JsonSchema\RefResolver(new JsonSchema\Uri\UriRetriever(), new JsonSchema\Uri\UriResolver()); $schemaPath = BASE_PATH.'/modules/tracker/schema/submission.json'; @@ -460,7 +457,21 @@ public function submissionValidate($args) } } else { $this->getLogger()->info('The supplied submissionDocument JSON for uuid '.$uuid.' is valid.'); - } + + /** @var Tracker_ProducerModel $producerModel */ + $producerModel = MidasLoader::loadModel('Producer', 'tracker'); + /** @var Tracker_ProducerDao $producerDao */ + $producerDao = $submissionDao->getProducer(); + if (!$producerModel->policyCheck( + $producerDao, + $user, + MIDAS_POLICY_WRITE + )) { + throw new Exception('Write permission on the producer required', 403); + } + $submissionDao->setDocument($submissionDocument); + $submissionModel->save($submissionDao); + } } } From 62f21205603754182f4bbaccfc745d2a20a1b07d Mon Sep 17 00:00:00 2001 From: mgrauer Date: Mon, 1 Aug 2016 22:25:56 -0400 Subject: [PATCH 12/20] Applied fixes from StyleCI --- modules/tracker/controllers/components/ApiComponent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 77ec8e378..5902f7e11 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -471,7 +471,7 @@ public function submissionValidate($args) } $submissionDao->setDocument($submissionDocument); $submissionModel->save($submissionDao); - } + } } } From ea56b9e8b24f05bc9179734e777504a70cddb368 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Tue, 2 Aug 2016 22:32:37 +0000 Subject: [PATCH 13/20] Add min and lower_is_better fields to aggregate metric spec model --- modules/tracker/database/mysql/2.0.4.sql | 2 ++ modules/tracker/database/upgrade/2.0.4.php | 5 +++++ modules/tracker/models/base/AggregateMetricSpecModelBase.php | 2 ++ modules/tracker/models/dao/AggregateMetricSpecDao.php | 4 ++++ 4 files changed, 13 insertions(+) diff --git a/modules/tracker/database/mysql/2.0.4.sql b/modules/tracker/database/mysql/2.0.4.sql index 3eb8d9f45..5956be60f 100644 --- a/modules/tracker/database/mysql/2.0.4.sql +++ b/modules/tracker/database/mysql/2.0.4.sql @@ -139,7 +139,9 @@ CREATE TABLE IF NOT EXISTS `tracker_aggregate_metric_spec` ( `abbreviation` varchar(255) NOT NULL DEFAULT '', `warning` double, `fail` double, + `min` double, `max` double, + `lower_is_better` tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (`aggregate_metric_spec_id`), KEY (`producer_id`) ) DEFAULT CHARSET=utf8; diff --git a/modules/tracker/database/upgrade/2.0.4.php b/modules/tracker/database/upgrade/2.0.4.php index e95506f6f..650827c91 100644 --- a/modules/tracker/database/upgrade/2.0.4.php +++ b/modules/tracker/database/upgrade/2.0.4.php @@ -39,5 +39,10 @@ public function mysql() 'ALTER TABLE `tracker_submission` '. ' ADD COLUMN `document` text;' ); + $this->db->query( + 'ALTER TABLE `tracker_aggregate_metric_spec` '. + ' ADD COLUMN `min` double,'. + ' ADD COLUMN `lower_is_better` tinyint(4) NOT NULL DEFAULT 0;' + ); } } diff --git a/modules/tracker/models/base/AggregateMetricSpecModelBase.php b/modules/tracker/models/base/AggregateMetricSpecModelBase.php index 9ef9a36b2..8f2eb1794 100644 --- a/modules/tracker/models/base/AggregateMetricSpecModelBase.php +++ b/modules/tracker/models/base/AggregateMetricSpecModelBase.php @@ -38,7 +38,9 @@ public function __construct() 'abbreviation' => array('type' => MIDAS_DATA), 'warning' => array('type' => MIDAS_DATA), 'fail' => array('type' => MIDAS_DATA), + 'min' => array('type' => MIDAS_DATA), 'max' => array('type' => MIDAS_DATA), + 'lower_is_better' => array('type' => MIDAS_DATA), 'producer' => array( 'type' => MIDAS_MANY_TO_ONE, 'model' => 'Producer', diff --git a/modules/tracker/models/dao/AggregateMetricSpecDao.php b/modules/tracker/models/dao/AggregateMetricSpecDao.php index 869f5ab1b..e4d0666df 100644 --- a/modules/tracker/models/dao/AggregateMetricSpecDao.php +++ b/modules/tracker/models/dao/AggregateMetricSpecDao.php @@ -37,8 +37,12 @@ * @method void setWarning(float $warning) * @method float getFail() * @method void setFail(float $fail) + * @method float getMin() + * @method void setMin(float $min) * @method float getMax() * @method void setMax(float $max) + * @method bool getLowerIsBetter() + * @method void setLowerIsBetter(boolean $lowerIsBetter) * @method Tracker_ProducerDao getProducer() * @method void setProducer(Tracker_ProducerDao $producerDao) */ From 532a0ae952676dad8a5d72f1f71e07437a694b06 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Tue, 2 Aug 2016 22:33:12 +0000 Subject: [PATCH 14/20] Set producer and metric name on created TrendThresholds --- modules/tracker/models/pdo/TrendThresholdModel.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/tracker/models/pdo/TrendThresholdModel.php b/modules/tracker/models/pdo/TrendThresholdModel.php index d8e668234..77c15515b 100644 --- a/modules/tracker/models/pdo/TrendThresholdModel.php +++ b/modules/tracker/models/pdo/TrendThresholdModel.php @@ -52,10 +52,12 @@ public function upsert( $sql = $this->database->select()->setIntegrityCheck(false) ->where('producer_id = ?', $producerDao->getProducerId()) ->where('metric_name = ?', $metricName); - /** @var Tracker_TrendThresholdDao $trendThresholdDao */ - $trendThresholdDao = $this->initDao('TrendThreshold', $this->database->fetchRow($sql), $this->moduleName); + /** @var Tracker_TrendThresholdDao $trendThresholdDao */ + $trendThresholdDao = $this->initDao('TrendThreshold', $this->database->fetchRow($sql), $this->moduleName); if ($trendThresholdDao === false) { $trendThresholdDao = MidasLoader::newDao('TrendThresholdDao', $this->moduleName); + $trendThresholdDao->setProducerId($producerDao->getProducerId()); + $trendThresholdDao->setMetricName($metricName); } if ($abbreviation !== false) { $trendThresholdDao->setAbbreviation($abbreviation); From 94a8e251f625876322069422e9ecccdbc49fc4c9 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Tue, 2 Aug 2016 22:33:57 +0000 Subject: [PATCH 15/20] Add upsert to AggregateMetricSpec model --- .../base/AggregateMetricSpecModelBase.php | 28 ++++++++ .../models/pdo/AggregateMetricSpecModel.php | 68 +++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/modules/tracker/models/base/AggregateMetricSpecModelBase.php b/modules/tracker/models/base/AggregateMetricSpecModelBase.php index 8f2eb1794..8833714ca 100644 --- a/modules/tracker/models/base/AggregateMetricSpecModelBase.php +++ b/modules/tracker/models/base/AggregateMetricSpecModelBase.php @@ -83,6 +83,34 @@ public function createAggregateMetricSpec($producerDao, $name, $spec, $descripti return $aggregateMetricSpecDao; } + /** + * Create or update a Tracker AggregateMetricSpec, matching on the Producer + * and spec fields. + * + * @param Tracker_ProducerDao $producerDao + * @param string $name name of the aggregate metric + * @param string $spec the spec for the aggregate metric spec + * @param false|string $abbreviation name abbreviation for the threshold + * @param false|string $description the description for the aggregate metric spec + * @param false|float $warning warning value for this threshold + * @param false|float $fail fail value for this threshold + * @param false|float $min min value for display of this threshold + * @param false|float $max max value for display of this threshold + * @param false|bool $lowerIsBetter whether lower values are better for this threshold + * @return false|Tracker_AggregateMetricSpecDao created from inputs + */ + abstract public function upsert( + $producerDao, + $name, + $spec, + $abbreviation = false, + $description, + $warning = false, + $fail = false, + $min = false, + $max = false, + $lowerIsBetter = false); + /** * Return all AggregateMetricSpecDaos tied to the producer. * diff --git a/modules/tracker/models/pdo/AggregateMetricSpecModel.php b/modules/tracker/models/pdo/AggregateMetricSpecModel.php index be0e34d4a..649f3c9d7 100644 --- a/modules/tracker/models/pdo/AggregateMetricSpecModel.php +++ b/modules/tracker/models/pdo/AggregateMetricSpecModel.php @@ -24,6 +24,74 @@ class Tracker_AggregateMetricSpecModel extends Tracker_AggregateMetricSpecModelBase { /** + * Create or update a Tracker AggregateMetricSpec, matching on the Producer + * and spec fields. + * + * @param Tracker_ProducerDao $producerDao + * @param string $name name of the aggregate metric + * @param string $spec the spec for the aggregate metric spec + * @param false|string $abbreviation name abbreviation for the threshold + * @param false|string $description the description for the aggregate metric spec + * @param false|float $warning warning value for this threshold + * @param false|float $fail fail value for this threshold + * @param false|float $min min value for display of this threshold + * @param false|float $max max value for display of this threshold + * @param false|bool $lowerIsBetter whether lower values are better for this threshold + * @return false|Tracker_AggregateMetricSpecDao created from inputs + */ + public function upsert( + $producerDao, + $name, + $spec, + $abbreviation = false, + $description, + $warning = false, + $fail = false, + $min = false, + $max = false, + $lowerIsBetter = false) + { + if (is_null($producerDao) || $producerDao === false) { + return false; + } + $sql = $this->database->select()->setIntegrityCheck(false) + ->where('producer_id = ?', $producerDao->getProducerId()) + ->where('spec = ?', $spec); + /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ + $aggregateMetricSpecDao = $this->initDao('AggregateMetricSpec', $this->database->fetchRow($sql), $this->moduleName); + if ($aggregateMetricSpecDao === false) { + $aggregateMetricSpecDao = MidasLoader::newDao('AggregateMetricSpecDao', $this->moduleName); + $aggregateMetricSpecDao->setProducerId($producerDao->getProducerId()); + $aggregateMetricSpecDao->setSpec($spec); + } + $aggregateMetricSpecDao->setName($name); + if ($abbreviation !== false) { + $aggregateMetricSpecDao->setAbbreviation($abbreviation); + } + if ($description !== false) { + $aggregateMetricSpecDao->setDescription($description); + } + if ($warning !== false) { + $aggregateMetricSpecDao->setWarning($warning); + } + if ($fail !== false) { + $aggregateMetricSpecDao->setFail($fail); + } + if ($min !== false) { + $aggregateMetricSpecDao->setMin($min); + } + if ($max !== false) { + $aggregateMetricSpecDao->setMax($max); + } + if ($lowerIsBetter !== false) { + $aggregateMetricSpecDao->setLowerIsBetter($lowerIsBetter); + } + $this->save($aggregateMetricSpecDao); + + return $aggregateMetricSpecDao; + } + + /** * Delete the given aggregate metric spec, any metrics calculated based on that spec, * and any associated notifications. * From 372f56df996dc1cc8285e4ecb48554ab762f93d3 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Tue, 2 Aug 2016 22:35:01 +0000 Subject: [PATCH 16/20] Update aggregate metrics, thresholds and notifications upon producer definition submission --- .../controllers/components/ApiComponent.php | 65 +++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 5902f7e11..7a5ec3937 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -415,15 +415,16 @@ public function submissionValidate($args) // Provide a default for $defaults so the below ?: logic works. $defaults = new stdClass(); } + // Add or update any key metrics and thresholds. + /** @var Tracker_TrendModel $trendModel */ + $trendModel = MidasLoader::loadModel('Trend', 'tracker'); + /** @var Tracker_TrendThresholdModel $trendThresholdModel */ + $trendThresholdModel = MidasLoader::loadModel('TrendThreshold', 'tracker'); $keyMetrics = $producerDefinition->key_metrics; /** @var stdClass $keyMetric */ foreach ($keyMetrics as $keyMetric) { - /** @var Tracker_TrendModel $trendModel */ - $trendModel = MidasLoader::loadModel('Trend', 'tracker'); // Set any needed trends to be key_metrics. $trendModel->setAggregatableTrendAsKeyMetrics($producerDao, $keyMetric->name); - /** @var Tracker_TrendThresholdModel $trendThresholdModel */ - $trendThresholdModel = MidasLoader::loadModel('TrendThreshold', 'tracker'); $trendThresholdModel->upsert($producerDao, $keyMetric->name, isset($keyMetric->abbreviation) ? $keyMetric->abbreviation : false, isset($keyMetric->warning) ? $keyMetric->warning : @@ -438,6 +439,62 @@ public function submissionValidate($args) (isset($defaults->lower_is_better) ? $defaults->lower_is_better : false) ); } + // Add or update any aggregate metrics and thresholds, based on matching + // the producer and spec. + $aggregateMetrics = $producerDefinition->aggregate_metrics; + /** @var Tracker_AggregateMetricSpecModel $aggregateMetricSpecModel */ + $aggregateMetricSpecModel = MidasLoader::loadModel('AggregateMetricSpec', 'tracker'); + /** @var Tracker_AggregateMetricNotificationModel $aggregateMetricNotificationModel */ + $aggregateMetricNotificationModel = MidasLoader::loadModel('AggregateMetricNotification', 'tracker'); + /** @var UserModel $userModel */ + $userModel = MidasLoader::loadModel('User'); + /** @var stdClass $aggregateMetric */ + foreach ($aggregateMetrics as $aggregateMetric) { + /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ + $aggregateMetricSpecDao = $aggregateMetricSpecModel->upsert($producerDao, $aggregateMetric->name, $aggregateMetric->definition, + isset($aggregateMetric->abbreviation) ? $aggregateMetric->abbreviation : false, + // Set empty string for description. + '', + isset($aggregateMetric->warning) ? $aggregateMetric->warning : + (isset($defaults->warning) ? $defaults->warning : false), + isset($aggregateMetric->fail) ? $aggregateMetric->fail : + (isset($defaults->fail) ? $defaults->fail : false), + isset($aggregateMetric->min) ? $aggregateMetric->min : + (isset($defaults->min) ? $defaults->min : false), + isset($aggregateMetric->max) ? $aggregateMetric->max : + (isset($defaults->max) ? $defaults->max : false), + isset($aggregateMetric->lower_is_better) ? $aggregateMetric->lower_is_better : + (isset($defaults->lower_is_better) ? $defaults->lower_is_better : false) + ); + // Delete any notifications tied to this Aggregate Metric, and create any + // as needed. + $staleNotifications = $aggregateMetricNotificationModel->findBy('aggregate_metric_spec_id', $aggregateMetricSpecDao->getAggregateMetricSpecId()); + /** @var Tracker_AggregateMetricNotificationDao $staleNotification */ + foreach ($staleNotifications as $staleNotification) { + $aggregateMetricNotificationModel->delete($staleNotification); + } + if (isset($aggregateMetric->notifications)) { + /** @var stdClass $notification */ + foreach ($aggregateMetric->notifications as $notification) { + /** @var Tracker_AggregateMetricNotificationDao $aggregateMetricNotificationDao */ + $aggregateMetricNotificationDao = MidasLoader::newDao('AggregateMetricNotificationDao', $this->moduleName); + $aggregateMetricNotificationDao->setAggregateMetricSpecId($aggregateMetricSpecDao->getAggregateMetricSpecId()); + $aggregateMetricNotificationDao->setBranch($notification->branch); + $aggregateMetricNotificationDao->setComparison($notification->comparison); + $aggregateMetricNotificationDao->setValue($notification->value); + $aggregateMetricNotificationModel->save($aggregateMetricNotificationDao); + if (isset($notification->emails)) { + foreach ($notification->emails as $email) { + // We can only add notifications for valid users. + $userDao = $userModel->getByEmail($email); + if ($userDao !== false) { + $aggregateMetricNotificationModel->createUserNotification($aggregateMetricNotificationDao, $userDao); + } + } + } + } + } + } } } From b382262df2d03b656f0f4a50db461fb44f713e28 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Tue, 2 Aug 2016 22:39:35 +0000 Subject: [PATCH 17/20] Add false as default for upsert description param --- modules/tracker/models/base/AggregateMetricSpecModelBase.php | 2 +- modules/tracker/models/pdo/AggregateMetricSpecModel.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/tracker/models/base/AggregateMetricSpecModelBase.php b/modules/tracker/models/base/AggregateMetricSpecModelBase.php index 8833714ca..ba0d69261 100644 --- a/modules/tracker/models/base/AggregateMetricSpecModelBase.php +++ b/modules/tracker/models/base/AggregateMetricSpecModelBase.php @@ -104,7 +104,7 @@ abstract public function upsert( $name, $spec, $abbreviation = false, - $description, + $description = false, $warning = false, $fail = false, $min = false, diff --git a/modules/tracker/models/pdo/AggregateMetricSpecModel.php b/modules/tracker/models/pdo/AggregateMetricSpecModel.php index 649f3c9d7..1e8c80fe0 100644 --- a/modules/tracker/models/pdo/AggregateMetricSpecModel.php +++ b/modules/tracker/models/pdo/AggregateMetricSpecModel.php @@ -44,7 +44,7 @@ public function upsert( $name, $spec, $abbreviation = false, - $description, + $description = false, $warning = false, $fail = false, $min = false, From 73a7fd3aa63956e2c997c756a0f6ff3d3854c32c Mon Sep 17 00:00:00 2001 From: mgrauer Date: Tue, 2 Aug 2016 18:40:17 -0400 Subject: [PATCH 18/20] Applied fixes from StyleCI --- .../controllers/components/ApiComponent.php | 2 +- .../models/pdo/AggregateMetricSpecModel.php | 72 +++++++++---------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 7a5ec3937..4d7ab1ba2 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -494,7 +494,7 @@ public function submissionValidate($args) } } } - } + } } } diff --git a/modules/tracker/models/pdo/AggregateMetricSpecModel.php b/modules/tracker/models/pdo/AggregateMetricSpecModel.php index 1e8c80fe0..5b9cbb324 100644 --- a/modules/tracker/models/pdo/AggregateMetricSpecModel.php +++ b/modules/tracker/models/pdo/AggregateMetricSpecModel.php @@ -50,48 +50,48 @@ public function upsert( $min = false, $max = false, $lowerIsBetter = false) - { - if (is_null($producerDao) || $producerDao === false) { - return false; - } - $sql = $this->database->select()->setIntegrityCheck(false) + { + if (is_null($producerDao) || $producerDao === false) { + return false; + } + $sql = $this->database->select()->setIntegrityCheck(false) ->where('producer_id = ?', $producerDao->getProducerId()) ->where('spec = ?', $spec); /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ $aggregateMetricSpecDao = $this->initDao('AggregateMetricSpec', $this->database->fetchRow($sql), $this->moduleName); - if ($aggregateMetricSpecDao === false) { - $aggregateMetricSpecDao = MidasLoader::newDao('AggregateMetricSpecDao', $this->moduleName); - $aggregateMetricSpecDao->setProducerId($producerDao->getProducerId()); - $aggregateMetricSpecDao->setSpec($spec); - } - $aggregateMetricSpecDao->setName($name); - if ($abbreviation !== false) { - $aggregateMetricSpecDao->setAbbreviation($abbreviation); - } - if ($description !== false) { - $aggregateMetricSpecDao->setDescription($description); - } - if ($warning !== false) { - $aggregateMetricSpecDao->setWarning($warning); - } - if ($fail !== false) { - $aggregateMetricSpecDao->setFail($fail); - } - if ($min !== false) { - $aggregateMetricSpecDao->setMin($min); - } - if ($max !== false) { - $aggregateMetricSpecDao->setMax($max); - } - if ($lowerIsBetter !== false) { - $aggregateMetricSpecDao->setLowerIsBetter($lowerIsBetter); - } - $this->save($aggregateMetricSpecDao); + if ($aggregateMetricSpecDao === false) { + $aggregateMetricSpecDao = MidasLoader::newDao('AggregateMetricSpecDao', $this->moduleName); + $aggregateMetricSpecDao->setProducerId($producerDao->getProducerId()); + $aggregateMetricSpecDao->setSpec($spec); + } + $aggregateMetricSpecDao->setName($name); + if ($abbreviation !== false) { + $aggregateMetricSpecDao->setAbbreviation($abbreviation); + } + if ($description !== false) { + $aggregateMetricSpecDao->setDescription($description); + } + if ($warning !== false) { + $aggregateMetricSpecDao->setWarning($warning); + } + if ($fail !== false) { + $aggregateMetricSpecDao->setFail($fail); + } + if ($min !== false) { + $aggregateMetricSpecDao->setMin($min); + } + if ($max !== false) { + $aggregateMetricSpecDao->setMax($max); + } + if ($lowerIsBetter !== false) { + $aggregateMetricSpecDao->setLowerIsBetter($lowerIsBetter); + } + $this->save($aggregateMetricSpecDao); - return $aggregateMetricSpecDao; - } + return $aggregateMetricSpecDao; + } - /** + /** * Delete the given aggregate metric spec, any metrics calculated based on that spec, * and any associated notifications. * From 29adfad2d00ab549369652d710d081f63b4a9578 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Wed, 3 Aug 2016 16:11:21 +0000 Subject: [PATCH 19/20] Replace double-ternary operators with helper function --- .../controllers/components/ApiComponent.php | 90 +++++++++++++------ 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 4d7ab1ba2..40f820f0c 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -336,7 +336,9 @@ public function submissionAdd($args) } /** - * Validate documents tied to a submission. + * Validate the producer configuration and submission documents that are tied + * to a submission, updating the properties of the producer based off of + * the producer configuration. * * @param uuid The uuid of the submission to validate documents for * @param producerConfig (Optional) JSON object describing the pipeline @@ -415,6 +417,47 @@ public function submissionValidate($args) // Provide a default for $defaults so the below ?: logic works. $defaults = new stdClass(); } + + /** + * Helper function to populate a metric based on the overall + * metrics defaults, overriding any default values with any + * specified in the metric itself, populating all properties with + * some unassigned (false or null) value if no other value is found. + * @param stdClass $metric the metric with specific values + * @return array populated metric values + */ + $populateMetricValues = function ($metric) use ($defaults) { + $populatedMetricUnassigned = array( + 'abbreviation' => false, + 'min' => false, + 'max' => false, + 'warning' => false, + 'fail' => false, + // Special handling as false is meaningful in this case. + 'lower_is_better' => null, + ); + $populatedMetric = array(); + /** @var string $key */ + /** @var mixed $unassignedValue */ + foreach ($populatedMetricUnassigned as $key => $unassignedValue) { + if (isset($metric->$key)) { + $populatedMetric[$key] = $metric->$key; + } elseif(isset($defaults->$key)) { + $populatedMetric[$key] = $defaults->$key; + } else { + $populatedMetric[$key] = $unassignedValue; + } + } + if ($populatedMetric['lower_is_better'] === null && + $populatedMetric['warning'] !== false && + $populatedMetric['fail'] !== false) { + // We can infer in this case. + $populatedMetric['lower_is_better'] = + $populatedMetric['warning'] < $populatedMetric['fail']; + } + return $populatedMetric; + }; + // Add or update any key metrics and thresholds. /** @var Tracker_TrendModel $trendModel */ $trendModel = MidasLoader::loadModel('Trend', 'tracker'); @@ -425,18 +468,16 @@ public function submissionValidate($args) foreach ($keyMetrics as $keyMetric) { // Set any needed trends to be key_metrics. $trendModel->setAggregatableTrendAsKeyMetrics($producerDao, $keyMetric->name); - $trendThresholdModel->upsert($producerDao, $keyMetric->name, - isset($keyMetric->abbreviation) ? $keyMetric->abbreviation : false, - isset($keyMetric->warning) ? $keyMetric->warning : - (isset($defaults->warning) ? $defaults->warning : false), - isset($keyMetric->fail) ? $keyMetric->fail : - (isset($defaults->fail) ? $defaults->fail : false), - isset($keyMetric->min) ? $keyMetric->min : - (isset($defaults->min) ? $defaults->min : false), - isset($keyMetric->max) ? $keyMetric->max : - (isset($defaults->max) ? $defaults->max : false), - isset($keyMetric->lower_is_better) ? $keyMetric->lower_is_better : - (isset($defaults->lower_is_better) ? $defaults->lower_is_better : false) + $metricValues = $populateMetricValues($keyMetric); + $trendThresholdModel->upsert( + $producerDao, + $keyMetric->name, + $metricValues['abbreviation'], + $metricValues['warning'], + $metricValues['fail'], + $metricValues['min'], + $metricValues['max'], + $metricValues['lower_is_better'] ); } // Add or update any aggregate metrics and thresholds, based on matching @@ -450,21 +491,20 @@ public function submissionValidate($args) $userModel = MidasLoader::loadModel('User'); /** @var stdClass $aggregateMetric */ foreach ($aggregateMetrics as $aggregateMetric) { + $metricValues = $populateMetricValues($aggregateMetric); /** @var Tracker_AggregateMetricSpecDao $aggregateMetricSpecDao */ - $aggregateMetricSpecDao = $aggregateMetricSpecModel->upsert($producerDao, $aggregateMetric->name, $aggregateMetric->definition, - isset($aggregateMetric->abbreviation) ? $aggregateMetric->abbreviation : false, + $aggregateMetricSpecDao = $aggregateMetricSpecModel->upsert( + $producerDao, + $aggregateMetric->name, + $aggregateMetric->definition, + $metricValues['abbreviation'], // Set empty string for description. '', - isset($aggregateMetric->warning) ? $aggregateMetric->warning : - (isset($defaults->warning) ? $defaults->warning : false), - isset($aggregateMetric->fail) ? $aggregateMetric->fail : - (isset($defaults->fail) ? $defaults->fail : false), - isset($aggregateMetric->min) ? $aggregateMetric->min : - (isset($defaults->min) ? $defaults->min : false), - isset($aggregateMetric->max) ? $aggregateMetric->max : - (isset($defaults->max) ? $defaults->max : false), - isset($aggregateMetric->lower_is_better) ? $aggregateMetric->lower_is_better : - (isset($defaults->lower_is_better) ? $defaults->lower_is_better : false) + $metricValues['warning'], + $metricValues['fail'], + $metricValues['min'], + $metricValues['max'], + $metricValues['lower_is_better'] ); // Delete any notifications tied to this Aggregate Metric, and create any // as needed. From 953bf4c2f6979fd6b7ead13f32dc50bd555c5e15 Mon Sep 17 00:00:00 2001 From: mgrauer Date: Wed, 3 Aug 2016 12:14:06 -0400 Subject: [PATCH 20/20] Applied fixes from StyleCI --- modules/tracker/controllers/components/ApiComponent.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/tracker/controllers/components/ApiComponent.php b/modules/tracker/controllers/components/ApiComponent.php index 40f820f0c..158ff1562 100644 --- a/modules/tracker/controllers/components/ApiComponent.php +++ b/modules/tracker/controllers/components/ApiComponent.php @@ -442,7 +442,7 @@ public function submissionValidate($args) foreach ($populatedMetricUnassigned as $key => $unassignedValue) { if (isset($metric->$key)) { $populatedMetric[$key] = $metric->$key; - } elseif(isset($defaults->$key)) { + } elseif (isset($defaults->$key)) { $populatedMetric[$key] = $defaults->$key; } else { $populatedMetric[$key] = $unassignedValue; @@ -455,6 +455,7 @@ public function submissionValidate($args) $populatedMetric['lower_is_better'] = $populatedMetric['warning'] < $populatedMetric['fail']; } + return $populatedMetric; };