Skip to content
Draft
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
11 changes: 11 additions & 0 deletions src/engine/BMInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ class BMInterface {
*/
protected static $conn = NULL;

/**
* Communication to notification service
*
* @var SnsClient
*/
protected static $snsClient = NULL;

/**
* Owning BMInterface, allows back navigation
*
Expand Down Expand Up @@ -73,10 +80,13 @@ public function __construct($isTest = FALSE) {

if ($isTest) {
require_once __DIR__.'/../../test/src/database/mysql.test.inc.php';
require_once __DIR__.'/../../test/src/notify/sns.test.php';
} else {
require_once __DIR__.'/../database/mysql.inc.php';
require_once __DIR__.'/../notify/sns.php';
}
self::$conn = conn();
self::$snsClient = snsClient();
}

/**
Expand All @@ -98,6 +108,7 @@ public function cast($className) {
$result->message = $this->message;
$result->timestamp = $this->timestamp;
$result::$conn = self::$conn;
$result::$snsClient = self::$snsClient;
return $result;
}

Expand Down
48 changes: 44 additions & 4 deletions src/engine/BMInterfaceGameAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ public function load_game_action_log(BMGame $game, $logEntryLimit) {
}

/**
* Save action log entries generated during the action in progress
* Save and publish action log entries generated during the action in progress
*
* Any game action entries which were generated should both be loaded into
* the message so the calling player can see them, and saved into the database
* Any game action entries which were generated should be loaded into
* the message so the calling player can see them, saved into the database,
* and published to notification service
*
* @param BMGame $game
* @return void
Expand All @@ -92,6 +93,8 @@ public function save_action_log($game) {
if (count($game->actionLog) > 0) {
$this->load_message_from_game_actions($game);
$this->log_game_actions($game);
$this->notify_game_actions($game);
$game->empty_action_log();
}
}

Expand Down Expand Up @@ -924,7 +927,6 @@ protected function log_game_actions(BMGame $game) {
$this->$typefunc($log_id, $gameAction->params);
}
}
$game->empty_action_log();
}

/**
Expand Down Expand Up @@ -956,4 +958,42 @@ protected function load_message_from_game_actions(BMGame $game) {
$this->set_message($message);
}
}

/**
* Publish new game action entries to notification service (SNS)
*
* @param BMGame $game
* @return void
*/
protected function notify_game_actions(BMGame $game) {

// function load_message_from_game_actions() already prepared a friendly message
// TODO: consider if constructing a more programmatic (json) message would be appropriate

$message = $this->message;

// TODO consider best way to get topic. possibly in sns.php
// maybe creating own wrapper object to wrap up SnSClient & topicArn
$topic = 'arn:aws:sns:us-east-1:111122223333:MyTopic';

try {
$result = self::$snsClient->publish([
'Message' => $message,
'TopicArn' => $topic,
'MessageAttributes' => [
'gameId' => [
'DataType' => 'String',
'StringValue' => $game->gameId
]
]
]);
// TODO: analyze result
} catch (AwsException $e) {
// output error message if fails
// TODO: what is the buttonweavers approach to error logging?
// TODO: consider swallowing all errors an treating notifications as optional
// notifications should probably not impede any other functionality
error_log($e->getMessage());
}
}
}
36 changes: 36 additions & 0 deletions src/notify/sns.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* sns : definition of communication to notification service
*
* @author danlangford
*/

// TODO: consider the requirements and recommendations
// https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_requirements.html

// TODO: consider installing dependency via Composer, phar, or zip file
// TODO: determine the proper way, in this project, to get the libs i need
require '/path/to/aws.phar'; // OOR require '/path/to/vendor/autoload.php'; OR require '/path/to/aws-autoloader.php';
use Aws\Sns\SnsClient;
use Aws\Exception\AwsException;

/**
* build a client
*
* @return SnSclient
*/
function snsClient() {

// credentials can be obtained from ENV vars like AWS_ACCESS_KEY_ID
// or credentials can be obtained from a single file on the host like $HOME/.aws/credentials
// for now ill assume a credentials file with profile: buttonweavers
// https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html

$SnSclient = new SnsClient([
'profile' => 'buttonweavers',
'region' => 'us-east-1',
'version' => 'latest'
]);

return $SnSclient;
}
33 changes: 33 additions & 0 deletions test/src/notify/sns.test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* sns : definition of communication to notification service
*/

// TODO: consider the appropriate test setup.
// connect to different SNS Topic? or stub out calls so they no-op? or provide choice?

// TODO: determine the proper way, in this project, to get the libs i need
require 'vendor/autoload.php';
use Aws\Sns\SnsClient;
use Aws\Exception\AwsException;

/**
* build a client
*
* @return SnSclient
*/
function snsClient() {

// credentials can be obtained from ENV vars like AWS_ACCESS_KEY_ID
// or credentials can be obtained from a single file on the host like $HOME/.aws/credentials
// for now ill assume a credentials file with profile: buttonweavers
// https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html

$SnSclient = new SnsClient([
'profile' => 'buttonweavers',
'region' => 'us-east-1',
'version' => '2010-03-31'
]);

return $SnSclient;
}