Page MenuHomeDevCentral

D612.id.diff
No OneTemporary

D612.id.diff

diff --git a/app/Events/JenkinsPayloadEvent.php b/app/Events/JenkinsPayloadEvent.php
new file mode 100644
--- /dev/null
+++ b/app/Events/JenkinsPayloadEvent.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Nasqueron\Notifications\Events;
+
+use Nasqueron\Notifications\Events\Event;
+use Illuminate\Queue\SerializesModels;
+
+class JenkinsPayloadEvent extends Event {
+ use SerializesModels;
+
+ /**
+ * The gate door which receives the request
+ * @var string
+ */
+ public $door;
+
+ /**
+ * The request content, as a structured data
+ * @var stdClass
+ */
+ public $payload;
+
+ /**
+ * Creates a new event instance.
+ *
+ * @param string $door
+ * @param stdClass $payload
+ */
+ public function __construct($door, $payload) {
+ $this->door = $door;
+ $this->payload = $payload;
+ }
+}
diff --git a/app/Http/Controllers/Gate/JenkinsGateController.php b/app/Http/Controllers/Gate/JenkinsGateController.php
new file mode 100644
--- /dev/null
+++ b/app/Http/Controllers/Gate/JenkinsGateController.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Nasqueron\Notifications\Http\Controllers\Gate;
+
+use Event;
+use Request;
+
+use Nasqueron\Notifications\Events\JenkinsPayloadEvent;
+
+class JenkinsGateController extends GateController {
+
+ ///
+ /// Private members
+ ///
+
+ /**
+ * The request content, as a structured data
+ *
+ * @var stdClass
+ */
+ private $payload;
+
+ /**
+ * The request content
+ *
+ * @var string
+ */
+ private $rawRequestContent;
+
+ ///
+ /// Constants
+ ///
+
+ /**
+ * The name of the service this gate accepts payload from.
+ */
+ const SERVICE_NAME = 'Jenkins';
+
+ ///
+ /// Request processing
+ ///
+
+ /**
+ * Handles POST requests
+ *
+ * @param Request $request the HTTP request
+ * @return Illuminate\Http\Response
+ */
+ public function onPost ($door) {
+ // Parses the request and check if it's legit
+
+ $this->door = $door;
+ $this->extractPayload();
+
+ // Process the request
+
+ $this->logRequest();
+ $this->onPayload();
+
+ // Output
+
+ return parent::renderReport();
+ }
+
+ /**
+ * Extracts payload from the request
+ */
+ protected function extractPayload () {
+ $request = Request::instance();
+ $this->rawRequestContent = $request->getContent();
+ $this->payload = json_decode($this->rawRequestContent);
+ }
+
+ ///
+ /// Payload processing
+ ///
+
+ protected function onPayload () {
+ $this->initializeReport();
+
+ Event::fire(new JenkinsPayloadEvent(
+ $this->door,
+ $this->payload
+ ));
+ }
+}
diff --git a/app/Jobs/FireJenkinsNotification.php b/app/Jobs/FireJenkinsNotification.php
new file mode 100644
--- /dev/null
+++ b/app/Jobs/FireJenkinsNotification.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Nasqueron\Notifications\Jobs;
+
+use Nasqueron\Notifications\Notifications\JenkinsNotification;
+use Nasqueron\Notifications\Events\JenkinsPayloadEvent;
+use Nasqueron\Notifications\Events\NotificationEvent;
+use Nasqueron\Notifications\Jobs\Job;
+
+use Event;
+
+class FireJenkinsNotification extends Job {
+
+ /**
+ * @var JenkinsPayloadEvent;
+ */
+ private $event;
+
+ /**
+ * Initializes a new instance of FireJenkinsNotification
+ *
+ * @param JenkinsPayloadEvent $event The event to notify
+ */
+ public function __construct (JenkinsPayloadEvent $event) {
+ $this->event = $event;
+ }
+
+ ///
+ /// Task
+ ///
+
+ /**
+ * Executes the job.
+ *
+ * @return void
+ */
+ public function handle() {
+ $notification = $this->createNotification();
+ Event::fire(new NotificationEvent($notification));
+ }
+
+ /**
+ * Creates a Jenkins notification
+ *
+ * @param JenkinsPayloadEvent $event
+ * @return Notification the notification
+ */
+ protected function createNotification() {
+ return new JenkinsNotification(
+ $this->event->door, // project
+ $this->event->payload // raw content
+ );
+ }
+}
diff --git a/app/Listeners/LastPayloadSaver.php b/app/Listeners/LastPayloadSaver.php
--- a/app/Listeners/LastPayloadSaver.php
+++ b/app/Listeners/LastPayloadSaver.php
@@ -42,6 +42,7 @@
$eventsToListen = [
'DockerHubPayloadEvent',
'GitHubPayloadEvent',
+ 'JenkinsPayloadEvent',
'PhabricatorPayloadEvent',
];
diff --git a/app/Listeners/NotificationListener.php b/app/Listeners/NotificationListener.php
--- a/app/Listeners/NotificationListener.php
+++ b/app/Listeners/NotificationListener.php
@@ -4,9 +4,11 @@
use Nasqueron\Notifications\Events\DockerHubPayloadEvent;
use Nasqueron\Notifications\Events\GitHubPayloadEvent;
+use Nasqueron\Notifications\Events\JenkinsPayloadEvent;
use Nasqueron\Notifications\Events\PhabricatorPayloadEvent;
use Nasqueron\Notifications\Jobs\FireDockerHubNotification;
use Nasqueron\Notifications\Jobs\FireGitHubNotification;
+use Nasqueron\Notifications\Jobs\FireJenkinsNotification;
use Nasqueron\Notifications\Jobs\FirePhabricatorNotification;
class NotificationListener {
@@ -48,6 +50,17 @@
$job->handle();
}
+ /**
+ * Handles a Jenkins payload event.
+ *
+ * @param JenkinsPayloadEvent $event
+ * @return void
+ */
+ public function onJenkinsPayload (JenkinsPayloadEvent $event) {
+ $job = new FireJenkinsNotification($event);
+ $job->handle();
+ }
+
///
/// Events listening
///
@@ -68,9 +81,14 @@
"$class@onGitHubPayload"
);
$events->listen(
+ 'Nasqueron\Notifications\Events\JenkinsPayloadEvent',
+ "$class@onJenkinsPayload"
+ );
+ $events->listen(
'Nasqueron\Notifications\Events\PhabricatorPayloadEvent',
"$class@onPhabricatorPayload"
);
+
}
}
diff --git a/app/Notifications/JenkinsNotification.php b/app/Notifications/JenkinsNotification.php
new file mode 100644
--- /dev/null
+++ b/app/Notifications/JenkinsNotification.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace Nasqueron\Notifications\Notifications;
+
+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 {
+
+ /**
+ * 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 the notification group.
+ *
+ * @return string
+ */
+ public function getGroup () {
+ return "ci"; // This is a temporary group, intended before mapping.
+ }
+
+}
diff --git a/config/gate.php b/config/gate.php
--- a/config/gate.php
+++ b/config/gate.php
@@ -15,6 +15,7 @@
'controllers' => [
'DockerHub',
'GitHub',
+ 'Jenkins',
'Phabricator',
],
diff --git a/tests/Http/PayloadFullTest.php b/tests/Http/PayloadFullTest.php
--- a/tests/Http/PayloadFullTest.php
+++ b/tests/Http/PayloadFullTest.php
@@ -74,6 +74,25 @@
}
/**
+ * Tests a Jenkins gate payload.
+ */
+ public function testJenkinsPayload () {
+ $payload = file_get_contents(__DIR__ . '/../data/payloads/JenkinsPayload.json');
+
+ $this->sendPayload(
+ '/gate/Jenkins/Acme', // A gate existing in data/credentials.json
+ $payload,
+ 'POST',
+ []
+ )->seeJson([
+ 'gate' => 'Jenkins',
+ 'door' => 'Acme',
+ 'action' => 'AMQPAction'
+ ]);
+ $this->assertResponseOk();
+ }
+
+ /**
* Tests a Phabricator gate payload.
*/
public function testPhabricatorPayload () {
diff --git a/tests/Notifications/JenkinsNotificationTest.php b/tests/Notifications/JenkinsNotificationTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Notifications/JenkinsNotificationTest.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Notifications;
+
+use Nasqueron\Notifications\Notifications\JenkinsNotification;
+use Nasqueron\Notifications\Tests\TestCase;
+
+class JenkinsNotificationTest extends TestCase {
+ /**
+ * @var Nasqueron\Notifications\Notifications\JenkinsNotification
+ */
+ private $notification;
+
+ /**
+ * @var stdClass
+ */
+ private $payload;
+
+ public function prepareNotification ($payloadFile) {
+ $path = __DIR__ . '/../data/payloads/' . $payloadFile;
+ $this->payload = json_decode(file_get_contents($path));
+
+ $this->notification = new JenkinsNotification(
+ "Acme",
+ $this->payload
+ );
+ }
+
+ public function testProperties () {
+ $this->prepareNotification('JenkinsPayload.json');
+
+ $this->assertSame("Jenkins", $this->notification->service);
+ $this->assertSame("Acme", $this->notification->project);
+ $this->assertSame("ci", $this->notification->group);
+ $this->assertSame($this->payload, $this->notification->rawContent);
+ $this->assertSame("completed.success", $this->notification->type);
+ $this->assertSame(
+ "Jenkins job asgard has been completed: success",
+ $this->notification->text
+ );
+ $this->assertSame(
+ "http://localhost:8080/job/asgard/18/",
+ $this->notification->link
+ );
+ }
+
+ public function testPropertiesForIncompletePayload () {
+ $this->prepareNotification('JenkinsStartedPayload.json');
+
+ $this->assertSame("started", $this->notification->type);
+ $this->assertSame(
+ "Jenkins job asgard has been started",
+ $this->notification->text
+ );
+ }
+}
diff --git a/tests/data/payloads/JenkinsPayload.json b/tests/data/payloads/JenkinsPayload.json
new file mode 100644
--- /dev/null
+++ b/tests/data/payloads/JenkinsPayload.json
@@ -0,0 +1,25 @@
+{
+ "name": "asgard",
+ "url": "job/asgard/",
+ "build": {
+ "full_url": "http://localhost:8080/job/asgard/18/",
+ "number": 18,
+ "phase": "COMPLETED",
+ "status": "SUCCESS",
+ "url": "job/asgard/18/",
+ "scm": {
+ "url": "https://github.com/evgeny-goldin/asgard.git",
+ "branch": "origin/master",
+ "commit": "c6d86dc654b12425e706bcf951adfe5a8627a517"
+ },
+ "artifacts": {
+ "asgard.war": {
+ "archive": "http://localhost:8080/job/asgard/18/artifact/asgard.war"
+ },
+ "asgard-standalone.jar": {
+ "archive": "http://localhost:8080/job/asgard/18/artifact/asgard-standalone.jar",
+ "s3": "https://s3-eu-west-1.amazonaws.com/evgenyg-bakery/asgard/asgard-standalone.jar"
+ }
+ }
+ }
+}
diff --git a/tests/data/payloads/JenkinsStartedPayload.json b/tests/data/payloads/JenkinsStartedPayload.json
new file mode 100644
--- /dev/null
+++ b/tests/data/payloads/JenkinsStartedPayload.json
@@ -0,0 +1,15 @@
+{
+ "name": "asgard",
+ "url": "job/asgard/",
+ "build": {
+ "full_url": "http://localhost:8080/job/asgard/18/",
+ "number": 18,
+ "phase": "STARTED",
+ "url": "job/asgard/18/",
+ "scm": {
+ "url": "https://github.com/evgeny-goldin/asgard.git",
+ "branch": "origin/master",
+ "commit": "c6d86dc654b12425e706bcf951adfe5a8627a517"
+ }
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 23, 10:12 (10 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2312270
Default Alt Text
D612.id.diff (12 KB)

Event Timeline