Page MenuHomeDevCentral

No OneTemporary

diff --git a/app/Analyzers/Jenkins/JenkinsPayloadAnalyzer.php b/app/Analyzers/Jenkins/JenkinsPayloadAnalyzer.php
new file mode 100644
index 0000000..e732b9d
--- /dev/null
+++ b/app/Analyzers/Jenkins/JenkinsPayloadAnalyzer.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Nasqueron\Notifications\Analyzers\Jenkins;
+
+use Config;
+use Storage;
+
+use InvalidArgumentException;
+
+class JenkinsPayloadAnalyzer {
+
+ ///
+ /// Private members
+ ///
+
+ /**
+ * The project name, used to load specific configuration and offer defaults
+ * @var string
+ */
+ private $project;
+
+ /**
+ * The request content, as a structured data
+ * @var stdClass
+ */
+ private $payload;
+
+ /**
+ * The configuration for the payload analyzer
+ * @var Nasqueron\Notifications\Analyzers\Jenkins\JenkinsPayloadAnalyzerConfiguration;
+ */
+ private $configuration;
+
+ ///
+ /// Constructor
+ ///
+
+ /**
+ * Creates a new JenkinsPayloadAnalyzer instance.
+ *
+ * @param string $project
+ * @param stdClass $payload
+ */
+ public function __construct($project, $payload) {
+ if (!is_object($payload)) {
+ throw new InvalidArgumentException("Payload must be an object.");
+ }
+
+ $this->project = $project;
+ $this->payload = $payload;
+
+ $this->loadConfiguration($project);
+ }
+
+ ///
+ /// Configuration
+ ///
+
+ /**
+ * The default name of the configuration file
+ */
+ const CONFIG_DEFAULT_FILE = 'default.json';
+
+ /**
+ * Gets the full path to the configuration file.
+ *
+ * @return string
+ */
+ public function getConfigurationFileName () {
+ $dir = Config::get('services.jenkins.analyzer.configDir');
+ $filename = $dir . '/' . $this->project . '.json';
+
+ if (!Storage::has($filename)) {
+ return $dir . '/' . static::CONFIG_DEFAULT_FILE;
+ }
+
+ return $filename;
+ }
+
+ public function loadConfiguration () {
+ $fileName = $this->getConfigurationFileName();
+ $mapper = new \JsonMapper();
+ $this->configuration = $mapper->map(
+ json_decode(Storage::get($fileName)),
+ new JenkinsPayloadAnalyzerConfiguration($this->project)
+ );
+ }
+
+ ///
+ /// Properties
+ ///
+
+ /**
+ * Gets the name of the repository.
+ *
+ * @var string
+ */
+ public function getJobName () {
+ return $this->payload->name;
+ }
+
+ /**
+ * Gets the group for a specific payload.
+ *
+ * @return string The group, central part of the routing key
+ */
+ public function getGroup () {
+ // If the payload is about some repository matching a table of
+ // symbols, we need to sort it to the right group.
+ $item = $this->getJobName();
+ foreach ($this->configuration->groupsMapping as $mapping) {
+ if ($mapping->doesItemBelong($item)) {
+ return $mapping->group;
+ }
+ }
+
+ return $this->configuration->getDefaultGroup();
+ }
+
+}
diff --git a/app/Analyzers/Jenkins/JenkinsPayloadAnalyzerConfiguration.php b/app/Analyzers/Jenkins/JenkinsPayloadAnalyzerConfiguration.php
new file mode 100644
index 0000000..7de1e82
--- /dev/null
+++ b/app/Analyzers/Jenkins/JenkinsPayloadAnalyzerConfiguration.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace Nasqueron\Notifications\Analyzers\Jenkins;
+
+class JenkinsPayloadAnalyzerConfiguration {
+
+ ///
+ /// Private members
+ ///
+
+ /**
+ * The project this configuration is for
+ *
+ * @var string
+ */
+ private $project;
+
+ ///
+ /// Public properties
+ ///
+
+ /**
+ * The default group to fallback for any event not mapped in another group
+ *
+ * @var string
+ */
+ public $defaultGroup;
+
+ /**
+ * An array of RepositoryGroupMapping objects to match jobs & groups
+ *
+ * @var \Nasqueron\Notifications\Analyzers\ItemGroupMapping[]
+ */
+ public $groupsMapping;
+
+ /**
+ * @var string[]
+ */
+ public $notifyOnlyOnFailureJobs;
+
+ ///
+ /// Constructor
+ ///
+
+ /**
+ * Initializes a new instance of the GitHubPayloadAnalyzerConfiguration class
+ *
+ * @param string $project The project name this configuration is related to
+ */
+ public function __construct ($project) {
+ $this->project = $project;
+ }
+
+ ///
+ /// Helper methods
+ ///
+
+ /**
+ * Gets the default group
+ *
+ * @return string the default group, as set in the configuration,
+ * or if omitted, the project name as fallback.
+ */
+ public function getDefaultGroup () {
+ if (empty($this->defaultGroup)) {
+ return strtolower($this->project);
+ }
+
+ return $this->defaultGroup;
+ }
+
+}
diff --git a/app/Notifications/JenkinsNotification.php b/app/Notifications/JenkinsNotification.php
index 7db16a6..65f605f 100644
--- a/app/Notifications/JenkinsNotification.php
+++ b/app/Notifications/JenkinsNotification.php
@@ -1,82 +1,103 @@
<?php
namespace Nasqueron\Notifications\Notifications;
+use Nasqueron\Notifications\Analyzers\Jenkins\JenkinsPayloadAnalyzer;
use Nasqueron\Notifications\Notification;
/**
* A Jenkins notification.
*
* This handles the JSON payloads sent by the following plugin:
* https://wiki.jenkins-ci.org/display/JENKINS/Notification+Plugin
*/
class JenkinsNotification extends Notification {
+ /**
+ * @var \Nasqueron\Notifications\Analyzers\Jenkins\JenkinsPayloadAnalyzer
+ */
+ private $analyzer = null;
+
/**
* Initializes a new instance of the JenkinsNotification class.
*
* @param string $project The project this message is for
* @param mixed $payload The message fired by Jenkins notification plugin
*/
public function __construct ($project, $payload) {
// Straightforward properties
$this->service = "Jenkins";
$this->project = $project;
$this->rawContent = $payload;
// Properties from the payload
$this->group = $this->getGroup();
$this->text = $this->getText();
$this->link = $payload->build->full_url;
$this->type = $this->getType();
}
/**
* Gets the notification type.
*
* @return string
*/
public function getType () {
$build = $this->rawContent->build;
$type = strtolower($build->phase);
if (property_exists($build, 'status')) {
$type .= '.';
$type .= $build->status;
}
return strtolower($type);
}
/**
* Gets the notification text. Intended to convey a short message (thing Twitter or IRC).
*
* @return string
*/
public function getText () {
$name = $this->rawContent->name;
$build = $this->rawContent->build;
$phase = strtolower($build->phase);
$text = "Jenkins job $name has been $phase";
if (property_exists($build, 'status')) {
$status = strtolower($build->status);
$text .= ": $status";
}
return $text;
}
+ /**
+ * Gets analyzer
+ *
+ * @return \Nasqueron\Notifications\Analyzers\Jenkins\JenkinsPayloadAnalyzer
+ */
+ private function getAnalyzer () {
+ if ($this->analyzer === null) {
+ $this->analyzer = new JenkinsPayloadAnalyzer(
+ $this->project,
+ $this->rawContent
+ );
+ }
+ return $this->analyzer;
+ }
+
/**
* Gets the notification group.
*
* @return string
*/
public function getGroup () {
- return "ci"; // This is a temporary group, intended before mapping.
+ return $this->getAnalyzer()->getGroup();
}
}
diff --git a/config/services.php b/config/services.php
index 812932c..6aa43a7 100644
--- a/config/services.php
+++ b/config/services.php
@@ -1,58 +1,64 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, Mandrill, and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
'mandrill' => [
'secret' => env('MANDRILL_SECRET'),
],
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-east-1',
],
'stripe' => [
'model' => Nasqueron\Notifications\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
'sentry' => [
'dsn' => env('SENTRY_DSN'),
],
'github' => [
'analyzer' => [
'configDir' => env('GITHUB_ANALYZER_CONFIG_DIR', 'GitHubPayloadAnalyzer')
]
],
+ 'jenkins' => [
+ 'analyzer' => [
+ 'configDir' => env('JENKINS_ANALYZER_CONFIG_DIR', 'JenkinsPayloadAnalyzer')
+ ]
+ ],
+
'phabricator' => [
'analyzer' => [
'configDir' => env('PHABRICATOR_ANALYZER_CONFIG_DIR', 'PhabricatorPayloadAnalyzer')
]
],
'gate' => [
'credentials' => env('CREDENTIALS', 'credentials.json'),
]
];
diff --git a/tests/Analyzers/Jenkins/JenkinsPayloadAnalyzerConfigurationTest.php b/tests/Analyzers/Jenkins/JenkinsPayloadAnalyzerConfigurationTest.php
new file mode 100644
index 0000000..9a47df4
--- /dev/null
+++ b/tests/Analyzers/Jenkins/JenkinsPayloadAnalyzerConfigurationTest.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Analyzers;
+
+use Illuminate\Foundation\Testing\WithoutMiddleware;
+
+use Nasqueron\Notifications\Analyzers\Jenkins\JenkinsPayloadAnalyzerConfiguration;
+use Nasqueron\Notifications\Analyzers\ItemGroupMapping;
+use Nasqueron\Notifications\Tests\TestCase;
+
+class JenkinsPayloadAnalyzerConfigurationTest extends TestCase {
+
+ /**
+ * Configuration
+ *
+ * @var Nasqueron\Notifications\Analyzers\Jenkins\JenkinsPayloadAnalyzerConfiguration
+ */
+ protected $configuration;
+
+ /**
+ * Prepares the test
+ */
+ public function setUp () {
+ $filename = __DIR__ . '/../../data/JenkinsPayloadAnalyzer/Nasqueron.json';
+ $mapper = new \JsonMapper();
+ $this->configuration = $mapper->map(
+ json_decode(file_get_contents($filename)),
+ new JenkinsPayloadAnalyzerConfiguration('Nasqueron')
+ );
+
+ parent::setUp();
+ }
+
+ /**
+ * Determines the JSON object is well parsed
+ */
+ public function testProperties () {
+ $this->assertSame("ci", $this->configuration->defaultGroup);
+
+ foreach ($this->configuration->groupsMapping as $item) {
+ $this->assertInstanceOf(ItemGroupMapping::class, $item);
+ }
+ }
+
+ ///
+ /// Tests for getDefaultGroup
+ ///
+
+ public function testGetDefaultGroup () {
+ $this->configuration->defaultGroup = "quux";
+ $this->assertSame("quux", $this->configuration->getDefaultGroup());
+ }
+
+ public function testGetDefaultGroupWhenNotInConfig () {
+ $this->configuration->defaultGroup = "";
+ $this->assertSame("nasqueron", $this->configuration->getDefaultGroup());
+
+ $this->configuration->defaultGroup = null;
+ $this->assertSame("nasqueron", $this->configuration->getDefaultGroup());
+ }
+
+}
diff --git a/tests/data/JenkinsPayloadAnalyzer/Nasqueron.json b/tests/data/JenkinsPayloadAnalyzer/Nasqueron.json
new file mode 100644
index 0000000..02867e3
--- /dev/null
+++ b/tests/data/JenkinsPayloadAnalyzer/Nasqueron.json
@@ -0,0 +1,27 @@
+{
+ "defaultGroup": "ci",
+ "groupsMapping": [
+ {
+ "group": "wikidata",
+ "items": [
+ "deploy-irc-daeghrefn-wikidata"
+ ]
+ },
+ {
+ "group": "ops",
+ "items": [
+ "deploy-website-*",
+ "test-prod-env"
+ ]
+ },
+ {
+ "group": "devtools",
+ "items": [
+ "test-notifications-*"
+ ]
+ }
+ ],
+ "notifyOnlyOnFailure": [
+ "test-prod-env"
+ ]
+}
diff --git a/tests/data/JenkinsPayloadAnalyzer/default.json b/tests/data/JenkinsPayloadAnalyzer/default.json
new file mode 100644
index 0000000..3ec0e5a
--- /dev/null
+++ b/tests/data/JenkinsPayloadAnalyzer/default.json
@@ -0,0 +1,5 @@
+{
+ "defaultGroup": "ci",
+ "groupsMapping": [],
+ "notifyOnlyOnFailure": []
+}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 16, 13:42 (21 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3170448
Default Alt Text
(12 KB)

Event Timeline