Skip to content
This repository has been archived by the owner on Mar 1, 2022. It is now read-only.

Analyzer runner w/ push notifications - squashed #65

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions module/Dashboard/Module.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<?php
namespace Dashboard;

use Dashboard\EventListener\AnalyzerViolation\PushNotifier;
use Dashboard\Model\Dao\GraphiteDao;
use Dashboard\Model\Dao\HerokuStatusDao;
use Dashboard\Model\Dao\WeatherDao;
use Zend\Cache\Storage\Adapter\Memcached;
use Zend\Cache\Storage\Adapter\MemcachedOptions;
use Zend\Console\Adapter\AdapterInterface as Console;
use Zend\EventManager\EventInterface;
use Zend\Mvc\MvcEvent;
use Zend\ServiceManager\ServiceManager;

class Module
Expand Down Expand Up @@ -87,10 +91,10 @@ public function getServiceConfig()
'WidgetFactory' => function (ServiceManager $serviceManager) {
return new Model\Widget\WidgetFactory($serviceManager->get('WidgetConfig'));
},
'CacheAdapter' => function ($serviceManager) {
'CacheAdapter' => function (ServiceManager $serviceManager) {
return new Memcached($serviceManager->get('CacheAdapterOptions'));
},
'CacheAdapterOptions' => function ($serviceManager) {
'CacheAdapterOptions' => function (ServiceManager $serviceManager) {
return new MemcachedOptions($serviceManager->get('Config')['dashboardCache']);
},
'SplunkDaoConfig' => function (ServiceManager $serviceManager) {
Expand Down Expand Up @@ -123,7 +127,7 @@ public function getServiceConfig()
'SlackDao' => function (ServiceManager $serviceManager) {
return new Model\Dao\SlackDao($serviceManager->get('SlackDaoConfig'));
},
'Parsedown' => function (ServiceManager $serviceManager) {
'Parsedown' => function () {
return new \Parsedown();
},
'BambooDaoConfig' => function (ServiceManager $serviceManager) {
Expand Down Expand Up @@ -162,10 +166,27 @@ public function getServiceConfig()
'GraphiteDaoConfig' => function (ServiceManager $serviceManager) {
return $serviceManager->get('Config')['GraphiteDao'];
},
'Dashboard\EventListener\AnalyzerViolation\PushNotifier' => function (ServiceManager $serviceManager) {
return new PushNotifier($serviceManager->get('Config')['push_notification']);
}
),
);
}

/**
* {@inheritdoc}
*
* @param EventInterface $e Event
* @return array|void
*/
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$serviceManager = $e->getApplication()->getServiceManager();

$eventManager->attach($serviceManager->get('Dashboard\EventListener\AnalyzerViolation\PushNotifier'));
}

/**
* Include all files in modules config/autoload if the directory exists
* @param string $configPath Optional path to the configs path
Expand Down Expand Up @@ -194,4 +215,16 @@ private function autoloadConfigs($configPath = __DIR__)

return $config;
}

public function getConsoleUsage(Console $console)
{
return array(
// Describe available commands
'monitor <config> [<widget>]' => 'Reset password for a user',

// Describe expected parameters
array( 'config', 'config name' ),
array( 'widget', 'widget name to listen to'),
);
}
}
27 changes: 27 additions & 0 deletions module/Dashboard/config/module.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,38 @@
),
),
),
'console' => [
'router' => [
'routes' => [
'monitor_aggregated' => [
'type' => 'simple',
'options' => [
'route' => 'monitor <configName>',
'defaults' => [
'controller' => 'Dashboard\Controller\CliController',
'action' => 'listenAggregated',
],
],
],
'monitor' => [
'type' => 'simple',
'options' => [
'route' => 'monitor <configName> <widgetId>',
'defaults' => [
'controller' => 'Dashboard\Controller\CliController',
'action' => 'listen',
],
],
],
],
],
],
'controllers' => array(
'invokables' => array(
'Dashboard\Controller\Dashboard' => 'Dashboard\Controller\DashboardController',
'Dashboard\Controller\LongPollingController' => 'Dashboard\Controller\LongPollingController',
'Dashboard\Controller\EventsApiController' => 'Dashboard\Controller\EventsApiController',
'Dashboard\Controller\CliController' => 'Dashboard\Controller\CliController',
),
),
'view_manager' => array(
Expand Down
27 changes: 27 additions & 0 deletions module/Dashboard/src/Dashboard/Controller/CliController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Dashboard\Controller;

use Dashboard\Model\AnalyzerRunner;
use Dashboard\Model\DashboardManager;
use Zend\Mvc\Controller\AbstractActionController;

class CliController extends AbstractActionController
{
public function listenAggregatedAction()
{
$configName = $this->params()->fromRoute('configName');
$dashboardManager = new DashboardManager($configName, $this->serviceLocator);
$analyzer = new AnalyzerRunner($dashboardManager);
$analyzer->runAggregated();
}

public function listenAction()
{
$configName = $this->params()->fromRoute('configName');
$widgetId = $this->params()->fromRoute('widgetId');
$dashboardManager = new DashboardManager($configName, $this->serviceLocator, $widgetId);
$analyzer = new AnalyzerRunner($dashboardManager);
$analyzer->run($widgetId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
<?php
/**
* @author pdziok
*/
namespace Dashboard\EventListener\AnalyzerViolation;

use Dashboard\Model\Analyzer\AnalyzerResult;
use Guzzle\Http\Client;
use Guzzle\Http\Exception\ServerErrorResponseException;
use Zend\EventManager\Event;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\ListenerAggregateInterface;
use Zend\Stdlib\CallbackHandler;

class PushNotifier implements ListenerAggregateInterface
{
private $privateKey;
private $publicKey;
private $apiUrl;
/** @var CallbackHandler */
private $handler;

/**
* PushNotifier constructor.
*
* @param $config
*/
public function __construct($config)
{
$this->privateKey = $config['privateKey'];
$this->publicKey = $config['publicKey'];
$this->apiUrl = $config['apiUrl'];
}

/**
* Attach one or more listeners
*
* Implementors may add an optional $priority argument; the EventManager
* implementation will pass this to the aggregate.
*
* @param EventManagerInterface $events
*
* @return void
*/
public function attach(EventManagerInterface $events)
{
$this->handler = $events->getSharedManager()->attach(
'Dashboard\Model\AnalyzerRunner',
'analyzer.violation',
[$this, 'handle']
);
}

/**
* Detach all previously attached listeners
*
* @param EventManagerInterface $events
*
* @return void
*/
public function detach(EventManagerInterface $events)
{
$events->getSharedManager()->detach('Dashboard\Model\AnalyzerRunner', $this->handler);
}

public function handle(Event $event)
{
$params = $event->getParams();
/** @var AnalyzerResult $analyzeResult */
list($analyzeResult, $config) = $params;

$platforms = $config['analyze']['notify']['platforms'];
$subscriptionIds = $config['analyze']['notify']['subscriptionIds'];
$message = $this->generateMessage($analyzeResult, $subscriptionIds, $platforms);
$request = $this->prepareRequest($message);

try {
$request->send();
} catch (ServerErrorResponseException $e) {
//shut up
}
}

private function generateSignature($method, $endpoint, $timestamp)
{
$hashSource = implode('|', [$method, $this->apiUrl . $endpoint, $this->publicKey, $timestamp]);

return hash_hmac('sha256', $hashSource, $this->privateKey);
}

/**
* @param $authSignature
* @param $timestamp
* @return array
*/
private function generateHeaders($authSignature, $timestamp)
{
$headers = [
"X-VgnoApiAuth-PublicKey" => $this->publicKey,
"X-VgnoApiAuth-Authenticate-Signature" => $authSignature,
"X-VgnoApiAuth-Authenticate-Timestamp" => $timestamp,
"Accept" => "application/json",
"Content-Type" => "application/json",
"User-Agent" => "STP RTM",
];

return $headers;
}

/**
* @param AnalyzerResult $analyzerResult
* @param $subscriptionIds
* @param $platforms
* @return array
*/
private function generateMessage(AnalyzerResult $analyzerResult, $subscriptionIds, $platforms)
{
$messageTitle = $this->generateMessageTitle($analyzerResult);
$messagePayload = $this->generateMessagePayload($analyzerResult);

$message = [
"date" => time(),
"sender" => "STP RTM",
"title" => $messageTitle,
"description" => '',
"sound" => "",
"image" => "",
"incrementor" => 0,
"payload" => $messagePayload,
"subscriptions" => $subscriptionIds,
"platforms" => $platforms,
];

return $message;
}

/**
* @param $analyzeResult
* @return string
*/
private function generateMessagePayload(AnalyzerResult $analyzeResult)
{
$messagePayload = json_encode([
'widgetId' => $analyzeResult->getWidgetId(),
'app' => $analyzeResult->getApplication(),
'status' => $analyzeResult->getStatus(),
]);

return $messagePayload;
}

/**
* @param $analyzeResult
* @return string
*/
private function generateMessageTitle(AnalyzerResult $analyzeResult)
{
$messageTitle = sprintf('%s: %s', $analyzeResult->getApplication(), $analyzeResult->getMessage());

return $messageTitle;
}

/**
* @return string
*/
private function generateTimestamp()
{
$timestamp = (new \DateTime())->setTimezone(new \DateTimeZone('Z'))->format('Y-m-d\TH:i:s\Z');

return $timestamp;
}

/**
* @param $message
* @return \Guzzle\Http\Message\EntityEnclosingRequestInterface|\Guzzle\Http\Message\RequestInterface
*/
private function prepareRequest($message)
{
$timestamp = $this->generateTimestamp();

$endpoint = 'message';
$authSignature = $this->generateSignature('POST', $endpoint, $timestamp);
$headers = $this->generateHeaders($authSignature, $timestamp);

$httpClient = new Client($this->apiUrl);
$request = $httpClient->post($endpoint, $headers, json_encode($message));

return $request;
}
}
Loading