From 091e09bbf17eac7965e9708c17cc46d0a64cafbb Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 10:13:41 -0500 Subject: [PATCH 01/30] OPS-981 | extract formatting of the logs while maintaining current format --- src/Process/Pool/LogFormatter.php | 34 +++++++++++ src/Process/Pool/LogFormatter.yml | 3 + src/Process/Pool/LogFormatterInterface.php | 15 +++++ src/Process/Pool/Logger.php | 66 ++++++++++++++++------ src/Process/Pool/Logger.yml | 3 +- src/Process/Pool/LoggerInterface.php | 7 ++- 6 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 src/Process/Pool/LogFormatter.php create mode 100644 src/Process/Pool/LogFormatter.yml create mode 100644 src/Process/Pool/LogFormatterInterface.php diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php new file mode 100644 index 00000000..a5214fc8 --- /dev/null +++ b/src/Process/Pool/LogFormatter.php @@ -0,0 +1,34 @@ +getMessageParts()); + fwrite(STDOUT, $message . "\n"); + } + + public function getMessageParts() : array + { + if ($this->messageParts === null) { + throw new \LogicException('LogFormatter messageParts has not been set.'); + } + + return $this->messageParts; + } + + public function setMessageParts(array $messageParts) : LogFormatterInterface + { + $this->messageParts = $messageParts; + + return $this; + } + +} diff --git a/src/Process/Pool/LogFormatter.yml b/src/Process/Pool/LogFormatter.yml new file mode 100644 index 00000000..542829f7 --- /dev/null +++ b/src/Process/Pool/LogFormatter.yml @@ -0,0 +1,3 @@ +services: + neighborhoods.kojo.process.log_formatter: + class: Neighborhoods\Kojo\Process\LogFormatter diff --git a/src/Process/Pool/LogFormatterInterface.php b/src/Process/Pool/LogFormatterInterface.php new file mode 100644 index 00000000..bcac5778 --- /dev/null +++ b/src/Process/Pool/LogFormatterInterface.php @@ -0,0 +1,15 @@ +_createOrUpdate(ProcessInterface::class, $process); return $this; } - protected function _getProcess(): ProcessInterface + protected function _getProcess() : ProcessInterface { return $this->_read(ProcessInterface::class); } @@ -39,53 +42,80 @@ public function log($level, $message, array $context = []) $processId = (string)$this->_getProcess()->getProcessId(); $paddedProcessId = str_pad($processId, $processIdPadding, ' ', STR_PAD_LEFT); $typeCode = str_pad($this->_getProcess()->getPath(), $processPathPadding, ' '); - }else { + } else { $paddedProcessId = str_pad('', $processIdPadding, '?', STR_PAD_LEFT); $typeCode = str_pad('', $processPathPadding, '?'); } $level = str_pad($level, 12, ' '); $referenceTime = $this->_getTime()->getUnixReferenceTimeNow(); - $format = "%s | %s | %s | %s | %s\n"; - fwrite(STDOUT, sprintf($format, $referenceTime, $level, $paddedProcessId, $typeCode, $message)); + + $this->getLogFormatter()->setMessageParts([ + $referenceTime, + $level, + $paddedProcessId, + $typeCode, + $message, + ] + )->writePipes(); } return; } - protected function _isEnabled(): bool + protected function _isEnabled() : bool { return $this->_read(self::PROP_IS_ENABLED); } - public function setIsEnabled(bool $isEnabled): LoggerInterface + public function setIsEnabled(bool $isEnabled) : LoggerInterface { $this->_create(self::PROP_IS_ENABLED, $isEnabled); return $this; } - public function setProcessPathPadding(int $processPathPadding): LoggerInterface + public function setProcessPathPadding(int $processPathPadding) : LoggerInterface { $this->_create(self::PROP_PROCESS_PATH_PADDING, $processPathPadding); return $this; } - protected function _getProcessPathPadding(): int + protected function _getProcessPathPadding() : int { return $this->_read(self::PROP_PROCESS_PATH_PADDING); } - public function setProcessIdPadding(int $processIdPadding): LoggerInterface + public function setProcessIdPadding(int $processIdPadding) : LoggerInterface { $this->_create(self::PROP_PROCESS_ID_PADDING, $processIdPadding); return $this; } - protected function _getProcessIdPadding(): int + protected function _getProcessIdPadding() : int { return $this->_read(self::PROP_PROCESS_ID_PADDING); } -} \ No newline at end of file + + public function getLogFormatter() : LogFormatterInterface + { + if ($this->log_formatter === null) { + throw new \LogicException('Logger log_formatter has not been set.'); + } + + return $this->log_formatter; + } + + public function setLogFormatter($log_formatter) : LoggerInterface + { + if ($this->log_formatter !== null) { + throw new \LogicException('Logger log_formatter already set.'); + } + + $this->log_formatter = $log_formatter; + + return $this; + } +} diff --git a/src/Process/Pool/Logger.yml b/src/Process/Pool/Logger.yml index e55995fe..01c44c05 100644 --- a/src/Process/Pool/Logger.yml +++ b/src/Process/Pool/Logger.yml @@ -10,5 +10,6 @@ services: - [setTime, ['@neighborhoods.pylon.time']] - [setProcessIdPadding, ['%process.pool.logger.process_id_padding%']] - [setProcessPathPadding, ['%process.pool.logger.path_padding%']] + - [setLogFormatter, ['@neighborhoods.kojo.process.log_formatter']] process.pool.logger: - alias: neighborhoods.kojo.process.pool.logger \ No newline at end of file + alias: neighborhoods.kojo.process.pool.logger diff --git a/src/Process/Pool/LoggerInterface.php b/src/Process/Pool/LoggerInterface.php index f85fb4ae..f570d602 100644 --- a/src/Process/Pool/LoggerInterface.php +++ b/src/Process/Pool/LoggerInterface.php @@ -3,6 +3,7 @@ namespace Neighborhoods\Kojo\Process\Pool; +use Neighborhoods\Kojo\Process\LogFormatterInterface; use Neighborhoods\Kojo\ProcessInterface; use Psr\Log; @@ -15,4 +16,8 @@ public function setIsEnabled(bool $isEnabled): LoggerInterface; public function setProcessPathPadding(int $processPathPadding): LoggerInterface; public function setProcessIdPadding(int $processIdPadding): LoggerInterface; -} \ No newline at end of file + + public function getLogFormatter() : LogFormatterInterface; + + public function setLogFormatter($log_formatter) : LoggerInterface; +} From cd6cd7613a56590ac3c848ea5b6f07fd66540b09 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 10:26:07 -0500 Subject: [PATCH 02/30] OPS-981 | correct namespace to include Pool --- src/Process/Pool/LogFormatter.php | 2 +- src/Process/Pool/LogFormatter.yml | 2 +- src/Process/Pool/LogFormatterInterface.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index a5214fc8..e868ad4d 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Neighborhoods\Kojo\Process; +namespace Neighborhoods\Kojo\Process\Pool; class LogFormatter implements LogFormatterInterface { diff --git a/src/Process/Pool/LogFormatter.yml b/src/Process/Pool/LogFormatter.yml index 542829f7..c92c5b00 100644 --- a/src/Process/Pool/LogFormatter.yml +++ b/src/Process/Pool/LogFormatter.yml @@ -1,3 +1,3 @@ services: neighborhoods.kojo.process.log_formatter: - class: Neighborhoods\Kojo\Process\LogFormatter + class: Neighborhoods\Kojo\Process\Pool\LogFormatter diff --git a/src/Process/Pool/LogFormatterInterface.php b/src/Process/Pool/LogFormatterInterface.php index bcac5778..b241e648 100644 --- a/src/Process/Pool/LogFormatterInterface.php +++ b/src/Process/Pool/LogFormatterInterface.php @@ -1,7 +1,7 @@ Date: Mon, 25 Jun 2018 10:29:02 -0500 Subject: [PATCH 03/30] OPS-981 | remove outdated 'use' statement --- src/Process/Pool/Logger.php | 3 +-- src/Process/Pool/LoggerInterface.php | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index d0d61c11..a5fdcb06 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -3,7 +3,6 @@ namespace Neighborhoods\Kojo\Process\Pool; -use Neighborhoods\Kojo\Process\LogFormatterInterface; use Neighborhoods\Kojo\ProcessInterface; use Neighborhoods\Pylon\Data\Property\Defensive; use Neighborhoods\Pylon\Time; @@ -108,7 +107,7 @@ public function getLogFormatter() : LogFormatterInterface return $this->log_formatter; } - public function setLogFormatter($log_formatter) : LoggerInterface + public function setLogFormatter(LogFormatterInterface $log_formatter) : LoggerInterface { if ($this->log_formatter !== null) { throw new \LogicException('Logger log_formatter already set.'); diff --git a/src/Process/Pool/LoggerInterface.php b/src/Process/Pool/LoggerInterface.php index f570d602..e236689e 100644 --- a/src/Process/Pool/LoggerInterface.php +++ b/src/Process/Pool/LoggerInterface.php @@ -3,7 +3,6 @@ namespace Neighborhoods\Kojo\Process\Pool; -use Neighborhoods\Kojo\Process\LogFormatterInterface; use Neighborhoods\Kojo\ProcessInterface; use Psr\Log; @@ -19,5 +18,5 @@ public function setProcessIdPadding(int $processIdPadding): LoggerInterface; public function getLogFormatter() : LogFormatterInterface; - public function setLogFormatter($log_formatter) : LoggerInterface; + public function setLogFormatter(LogFormatterInterface $log_formatter) : LoggerInterface; } From 27683e01f8d89cc8f2c874dc887ba9caa2ae3468 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 10:56:23 -0500 Subject: [PATCH 04/30] OPS-981 | pass an associative array and allow json output --- src/Process/Pool/LogFormatter.php | 18 ++++++++++++++++-- src/Process/Pool/LogFormatterInterface.php | 2 ++ src/Process/Pool/Logger.php | 20 ++++++++++++-------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index e868ad4d..af8e5ca9 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -11,8 +11,14 @@ class LogFormatter implements LogFormatterInterface public function writePipes() { - $message = implode(' | ', $this->getMessageParts()); - fwrite(STDOUT, $message . "\n"); + $message = implode(' | ', array_values($this->getMessageParts())); + $this->write($message); + } + + public function writeJson() + { + $message = json_encode($this->getMessageParts()); + $this->write($message); } public function getMessageParts() : array @@ -31,4 +37,12 @@ public function setMessageParts(array $messageParts) : LogFormatterInterface return $this; } + /** + * @param $message + */ + protected function write($message) : void + { + fwrite(STDOUT, $message . "\n"); + } + } diff --git a/src/Process/Pool/LogFormatterInterface.php b/src/Process/Pool/LogFormatterInterface.php index b241e648..96b1df28 100644 --- a/src/Process/Pool/LogFormatterInterface.php +++ b/src/Process/Pool/LogFormatterInterface.php @@ -12,4 +12,6 @@ public function writePipes(); public function getMessageParts() : array; public function setMessageParts(array $messageParts) : LogFormatterInterface; + + public function writeJson(); } diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index a5fdcb06..6357fcb3 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -49,14 +49,18 @@ public function log($level, $message, array $context = []) $level = str_pad($level, 12, ' '); $referenceTime = $this->_getTime()->getUnixReferenceTimeNow(); - $this->getLogFormatter()->setMessageParts([ - $referenceTime, - $level, - $paddedProcessId, - $typeCode, - $message, - ] - )->writePipes(); + $messageParts = [ + 'time' => $referenceTime, + 'level' => $level, + 'processId' => $paddedProcessId, + 'typeCode' => $typeCode, + 'message' => $message, + ]; + if ((int)$processId % 2 === 0) { + $this->getLogFormatter()->setMessageParts($messageParts)->writePipes(); + } else { + $this->getLogFormatter()->setMessageParts($messageParts)->writeJson(); + } } return; From 27fc262acfa2554a02f099758755fed51556345c Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 11:17:01 -0500 Subject: [PATCH 05/30] OPS-981 | write JSON only with no padding --- src/Process/Pool/Logger.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 6357fcb3..eb16f5e8 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -46,21 +46,18 @@ public function log($level, $message, array $context = []) $typeCode = str_pad('', $processPathPadding, '?'); } - $level = str_pad($level, 12, ' '); +// $level = str_pad($level, 12, ' '); $referenceTime = $this->_getTime()->getUnixReferenceTimeNow(); $messageParts = [ 'time' => $referenceTime, 'level' => $level, - 'processId' => $paddedProcessId, - 'typeCode' => $typeCode, + 'processId' => $this->_getProcess()->getProcessId(), + 'typeCode' => $this->_getProcess()->getPath(), 'message' => $message, ]; - if ((int)$processId % 2 === 0) { - $this->getLogFormatter()->setMessageParts($messageParts)->writePipes(); - } else { - $this->getLogFormatter()->setMessageParts($messageParts)->writeJson(); - } + + $this->getLogFormatter()->setMessageParts($messageParts)->writeJson(); } return; From 39a10abff963daaa5ba3a4b99096060be2dfb902 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 11:49:10 -0500 Subject: [PATCH 06/30] OPS-981 | hard code the message padding values --- src/Process/Pool/LogFormatter.php | 17 ++++++++++++++++- src/Process/Pool/Logger.php | 11 +++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index af8e5ca9..928f1128 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -11,13 +11,28 @@ class LogFormatter implements LogFormatterInterface public function writePipes() { + $messageParts = [ + 'time' => $this->getMessageParts()['time'], + 'level' => $this->getMessageParts()['level'], + 'processId' => $this->getMessageParts()['processId'], + 'typeCode' => $this->getMessageParts()['typeCode'], + 'message' => $this->getMessageParts()['message'], + ]; + + $processIdPadding = 6; + $processPathPadding = 80; + + $messageParts['processId'] = str_pad($messageParts['processId'], $processIdPadding, ' ', STR_PAD_LEFT); + $messageParts['typeCode'] = str_pad($messageParts['typeCode'], $processPathPadding, ' '); + $messageParts['level'] = str_pad($messageParts['level'], 12, ' '); + $message = implode(' | ', array_values($this->getMessageParts())); $this->write($message); } public function writeJson() { - $message = json_encode($this->getMessageParts()); + $message = json_encode($this->getMessageParts()); $this->write($message); } diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index eb16f5e8..51191434 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -35,24 +35,19 @@ protected function _getProcess() : ProcessInterface public function log($level, $message, array $context = []) { if ($this->_isEnabled() === true) { - $processIdPadding = $this->_getProcessIdPadding(); - $processPathPadding = $this->_getProcessPathPadding(); + if ($this->_exists(ProcessInterface::class)) { $processId = (string)$this->_getProcess()->getProcessId(); - $paddedProcessId = str_pad($processId, $processIdPadding, ' ', STR_PAD_LEFT); - $typeCode = str_pad($this->_getProcess()->getPath(), $processPathPadding, ' '); } else { - $paddedProcessId = str_pad('', $processIdPadding, '?', STR_PAD_LEFT); - $typeCode = str_pad('', $processPathPadding, '?'); + $processId = '?'; } -// $level = str_pad($level, 12, ' '); $referenceTime = $this->_getTime()->getUnixReferenceTimeNow(); $messageParts = [ 'time' => $referenceTime, 'level' => $level, - 'processId' => $this->_getProcess()->getProcessId(), + 'processId' => $processId, 'typeCode' => $this->_getProcess()->getPath(), 'message' => $message, ]; From b4e44ec03370b372ed7895714a01cb229affd8db Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 11:51:52 -0500 Subject: [PATCH 07/30] OPS-981 | force to write pipes --- src/Process/Pool/Logger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 51191434..209d149a 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -52,7 +52,7 @@ public function log($level, $message, array $context = []) 'message' => $message, ]; - $this->getLogFormatter()->setMessageParts($messageParts)->writeJson(); + $this->getLogFormatter()->setMessageParts($messageParts)->writePipes(); } return; From 10d96ef2979b1fdea9981d95f80e1ef8a9b8c976 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 11:52:56 -0500 Subject: [PATCH 08/30] OPS-981 | use the padded message parts --- src/Process/Pool/LogFormatter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index 928f1128..660fda30 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -26,7 +26,7 @@ public function writePipes() $messageParts['typeCode'] = str_pad($messageParts['typeCode'], $processPathPadding, ' '); $messageParts['level'] = str_pad($messageParts['level'], 12, ' '); - $message = implode(' | ', array_values($this->getMessageParts())); + $message = implode(' | ', array_values($messageParts)); $this->write($message); } From 4a5c35756b4af3a1162a0d3dfb296cdf7e91717a Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 12:08:27 -0500 Subject: [PATCH 09/30] OPS-981 | move the writing back to the Logger --- src/Process/Pool/LogFormatter.php | 29 +++++++++++++++------- src/Process/Pool/LogFormatterInterface.php | 8 ++++-- src/Process/Pool/Logger.php | 3 ++- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index 660fda30..edd2f982 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -9,7 +9,10 @@ class LogFormatter implements LogFormatterInterface /** @var array */ protected $messageParts; - public function writePipes() + /** @var string */ + protected $formattedMessage; + + public function formatPipes() { $messageParts = [ 'time' => $this->getMessageParts()['time'], @@ -27,13 +30,13 @@ public function writePipes() $messageParts['level'] = str_pad($messageParts['level'], 12, ' '); $message = implode(' | ', array_values($messageParts)); - $this->write($message); + $this->setFormattedMessage($message); } - public function writeJson() + public function formatJson() { $message = json_encode($this->getMessageParts()); - $this->write($message); + $this->setFormattedMessage($message); } public function getMessageParts() : array @@ -52,12 +55,20 @@ public function setMessageParts(array $messageParts) : LogFormatterInterface return $this; } - /** - * @param $message - */ - protected function write($message) : void + public function getFormattedMessage() : string + { + if ($this->formattedMessage === null) { + throw new \LogicException('LogFormatter formattedMessage has not been set.'); + } + + return $this->formattedMessage; + } + + public function setFormattedMessage(string $formattedMessage) : LogFormatterInterface { - fwrite(STDOUT, $message . "\n"); + $this->formattedMessage = $formattedMessage; + + return $this; } } diff --git a/src/Process/Pool/LogFormatterInterface.php b/src/Process/Pool/LogFormatterInterface.php index 96b1df28..087c8cc2 100644 --- a/src/Process/Pool/LogFormatterInterface.php +++ b/src/Process/Pool/LogFormatterInterface.php @@ -7,11 +7,15 @@ interface LogFormatterInterface { - public function writePipes(); + public function formatPipes(); public function getMessageParts() : array; public function setMessageParts(array $messageParts) : LogFormatterInterface; - public function writeJson(); + public function formatJson(); + + public function getFormattedMessage() : string; + + public function setFormattedMessage(string $formattedMessage) : LogFormatterInterface; } diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 209d149a..a8fb1584 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -52,7 +52,8 @@ public function log($level, $message, array $context = []) 'message' => $message, ]; - $this->getLogFormatter()->setMessageParts($messageParts)->writePipes(); + $this->getLogFormatter()->setMessageParts($messageParts)->formatPipes(); + fwrite(STDOUT, $this->getLogFormatter()->getFormattedMessage() . "\n"); } return; From a840610d40ecb94794110ac0983fd60a2169aca9 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 12:39:44 -0500 Subject: [PATCH 10/30] OPS-981 | use a generic format() method to toggle format type --- src/Process/Pool/LogFormatter.php | 57 ++++++++++++++++++++-- src/Process/Pool/LogFormatter.yml | 6 +++ src/Process/Pool/LogFormatterInterface.php | 12 +++-- src/Process/Pool/Logger.php | 30 +----------- src/Process/Pool/Logger.yml | 4 -- src/Process/Pool/LoggerInterface.php | 4 -- 6 files changed, 68 insertions(+), 45 deletions(-) diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index edd2f982..335da631 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -1,18 +1,37 @@ getMessageParts()['processId'] % 2 == 0){ + $this->formatJson(); + } else { + $this->formatPipes(); + } + + return $this; + } + + public function formatPipes() : LogFormatterInterface { $messageParts = [ 'time' => $this->getMessageParts()['time'], @@ -22,8 +41,8 @@ public function formatPipes() 'message' => $this->getMessageParts()['message'], ]; - $processIdPadding = 6; - $processPathPadding = 80; + $processIdPadding = $this->getProcessIdPadding(); + $processPathPadding = $this->getProcessPathPadding(); $messageParts['processId'] = str_pad($messageParts['processId'], $processIdPadding, ' ', STR_PAD_LEFT); $messageParts['typeCode'] = str_pad($messageParts['typeCode'], $processPathPadding, ' '); @@ -31,12 +50,16 @@ public function formatPipes() $message = implode(' | ', array_values($messageParts)); $this->setFormattedMessage($message); + + return $this; } - public function formatJson() + public function formatJson() : LogFormatterInterface { $message = json_encode($this->getMessageParts()); $this->setFormattedMessage($message); + + return $this; } public function getMessageParts() : array @@ -71,4 +94,28 @@ public function setFormattedMessage(string $formattedMessage) : LogFormatterInte return $this; } + public function setProcessPathPadding(int $processPathPadding) : LogFormatterInterface + { + $this->_create(self::PROP_PROCESS_PATH_PADDING, $processPathPadding); + + return $this; + } + + protected function getProcessPathPadding() : int + { + return $this->_read(self::PROP_PROCESS_PATH_PADDING); + } + + public function setProcessIdPadding(int $processIdPadding) : LogFormatterInterface + { + $this->_create(self::PROP_PROCESS_ID_PADDING, $processIdPadding); + + return $this; + } + + protected function getProcessIdPadding() : int + { + return $this->_read(self::PROP_PROCESS_ID_PADDING); + } + } diff --git a/src/Process/Pool/LogFormatter.yml b/src/Process/Pool/LogFormatter.yml index c92c5b00..44e476c9 100644 --- a/src/Process/Pool/LogFormatter.yml +++ b/src/Process/Pool/LogFormatter.yml @@ -1,3 +1,9 @@ +parameters: + process.pool.logger.process_id_padding: 6 + process.pool.logger.path_padding: 80 services: neighborhoods.kojo.process.log_formatter: class: Neighborhoods\Kojo\Process\Pool\LogFormatter + calls: + - [setProcessIdPadding, ['%process.pool.logger.process_id_padding%']] + - [setProcessPathPadding, ['%process.pool.logger.path_padding%']]] diff --git a/src/Process/Pool/LogFormatterInterface.php b/src/Process/Pool/LogFormatterInterface.php index 087c8cc2..ab6651f5 100644 --- a/src/Process/Pool/LogFormatterInterface.php +++ b/src/Process/Pool/LogFormatterInterface.php @@ -7,15 +7,21 @@ interface LogFormatterInterface { - public function formatPipes(); + public function format() : LogFormatterInterface; + + public function formatPipes() : LogFormatterInterface; + + public function formatJson() : LogFormatterInterface; public function getMessageParts() : array; public function setMessageParts(array $messageParts) : LogFormatterInterface; - public function formatJson(); - public function getFormattedMessage() : string; public function setFormattedMessage(string $formattedMessage) : LogFormatterInterface; + + public function setProcessPathPadding(int $processPathPadding) : LogFormatterInterface; + + public function setProcessIdPadding(int $processIdPadding) : LogFormatterInterface; } diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index a8fb1584..578d3893 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -12,11 +12,7 @@ class Logger extends Log\AbstractLogger implements LoggerInterface { use Time\AwareTrait; use Defensive\AwareTrait; - const PAD_PID = 6; - const PAD_PATH = 50; const PROP_IS_ENABLED = 'is_enabled'; - const PROP_PROCESS_PATH_PADDING = 'process_path_padding'; - const PROP_PROCESS_ID_PADDING = 'process_id_padding'; protected $log_formatter; @@ -52,7 +48,7 @@ public function log($level, $message, array $context = []) 'message' => $message, ]; - $this->getLogFormatter()->setMessageParts($messageParts)->formatPipes(); + $this->getLogFormatter()->setMessageParts($messageParts)->format(); fwrite(STDOUT, $this->getLogFormatter()->getFormattedMessage() . "\n"); } @@ -71,30 +67,6 @@ public function setIsEnabled(bool $isEnabled) : LoggerInterface return $this; } - public function setProcessPathPadding(int $processPathPadding) : LoggerInterface - { - $this->_create(self::PROP_PROCESS_PATH_PADDING, $processPathPadding); - - return $this; - } - - protected function _getProcessPathPadding() : int - { - return $this->_read(self::PROP_PROCESS_PATH_PADDING); - } - - public function setProcessIdPadding(int $processIdPadding) : LoggerInterface - { - $this->_create(self::PROP_PROCESS_ID_PADDING, $processIdPadding); - - return $this; - } - - protected function _getProcessIdPadding() : int - { - return $this->_read(self::PROP_PROCESS_ID_PADDING); - } - public function getLogFormatter() : LogFormatterInterface { if ($this->log_formatter === null) { diff --git a/src/Process/Pool/Logger.yml b/src/Process/Pool/Logger.yml index 01c44c05..3ae2dcf5 100644 --- a/src/Process/Pool/Logger.yml +++ b/src/Process/Pool/Logger.yml @@ -1,6 +1,4 @@ parameters: - process.pool.logger.process_id_padding: 6 - process.pool.logger.path_padding: 80 process.pool.logger.is_enabled: true services: neighborhoods.kojo.process.pool.logger: @@ -8,8 +6,6 @@ services: calls: - [setIsEnabled, ['%process.pool.logger.is_enabled%']] - [setTime, ['@neighborhoods.pylon.time']] - - [setProcessIdPadding, ['%process.pool.logger.process_id_padding%']] - - [setProcessPathPadding, ['%process.pool.logger.path_padding%']] - [setLogFormatter, ['@neighborhoods.kojo.process.log_formatter']] process.pool.logger: alias: neighborhoods.kojo.process.pool.logger diff --git a/src/Process/Pool/LoggerInterface.php b/src/Process/Pool/LoggerInterface.php index e236689e..47117afd 100644 --- a/src/Process/Pool/LoggerInterface.php +++ b/src/Process/Pool/LoggerInterface.php @@ -12,10 +12,6 @@ public function setProcess(ProcessInterface $process): LoggerInterface; public function setIsEnabled(bool $isEnabled): LoggerInterface; - public function setProcessPathPadding(int $processPathPadding): LoggerInterface; - - public function setProcessIdPadding(int $processIdPadding): LoggerInterface; - public function getLogFormatter() : LogFormatterInterface; public function setLogFormatter(LogFormatterInterface $log_formatter) : LoggerInterface; From a64f762db9117d696e176f07d594350ee530457e Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Mon, 25 Jun 2018 12:41:23 -0500 Subject: [PATCH 11/30] OPS-981 | remove extra closing bracket --- src/Process/Pool/LogFormatter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Process/Pool/LogFormatter.yml b/src/Process/Pool/LogFormatter.yml index 44e476c9..9c0d031a 100644 --- a/src/Process/Pool/LogFormatter.yml +++ b/src/Process/Pool/LogFormatter.yml @@ -6,4 +6,4 @@ services: class: Neighborhoods\Kojo\Process\Pool\LogFormatter calls: - [setProcessIdPadding, ['%process.pool.logger.process_id_padding%']] - - [setProcessPathPadding, ['%process.pool.logger.path_padding%']]] + - [setProcessPathPadding, ['%process.pool.logger.path_padding%']] From 38edeb59f41a01d2446b216ac82ce5e1c47bf29e Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Tue, 26 Jun 2018 08:56:44 -0500 Subject: [PATCH 12/30] OPS-981 | pass the log_format as an env variable --- src/Environment/Parameters.yml | 3 +- src/Process/Pool/LogFormatter.php | 56 ++++++++++++++++------ src/Process/Pool/LogFormatter.yml | 1 + src/Process/Pool/LogFormatterInterface.php | 2 + 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/Environment/Parameters.yml b/src/Environment/Parameters.yml index 0f2b3a14..d9fe967d 100644 --- a/src/Environment/Parameters.yml +++ b/src/Environment/Parameters.yml @@ -5,4 +5,5 @@ parameters: neighborhoods.kojo.environment.parameters.database_password: '' neighborhoods.kojo.environment.parameters.database_adapter: '' neighborhoods.kojo.environment.parameters.database_host: '' - neighborhoods.kojo.environment.parameters.database_name: '' \ No newline at end of file + neighborhoods.kojo.environment.parameters.database_name: '' + neighborhoods.kojo.environment.parameters.log_format: '' diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index 335da631..895749c1 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -13,6 +13,13 @@ class LogFormatter implements LogFormatterInterface const PAD_PATH = 50; const PROP_PROCESS_PATH_PADDING = 'process_path_padding'; const PROP_PROCESS_ID_PADDING = 'process_id_padding'; + const PROP_LOG_FORMAT = 'log_format'; + + const KEY_TIME = 'time'; + const KEY_LEVEL = 'level'; + const KEY_PROCESS_ID = 'processId'; + const KEY_TYPE_CODE = 'typeCode'; + const KEY_MESSAGE = 'message'; /** @var array */ protected $messageParts; @@ -20,12 +27,13 @@ class LogFormatter implements LogFormatterInterface /** @var string */ protected $formattedMessage; - public function format(): LogFormatterInterface + + public function format() : LogFormatterInterface { - if ((int)$this->getMessageParts()['processId'] % 2 == 0){ - $this->formatJson(); - } else { + if ($this->hasLogFormat() && $this->getLogFormat() === 'pipes'){ $this->formatPipes(); + } else { + $this->formatJson(); } return $this; @@ -33,22 +41,26 @@ public function format(): LogFormatterInterface public function formatPipes() : LogFormatterInterface { - $messageParts = [ - 'time' => $this->getMessageParts()['time'], - 'level' => $this->getMessageParts()['level'], - 'processId' => $this->getMessageParts()['processId'], - 'typeCode' => $this->getMessageParts()['typeCode'], - 'message' => $this->getMessageParts()['message'], + $paddedMessage = [ + self::KEY_TIME => $this->getMessageParts()[self::KEY_TIME], + self::KEY_LEVEL => $this->getMessageParts()[self::KEY_LEVEL], + self::KEY_PROCESS_ID => $this->getMessageParts()[self::KEY_PROCESS_ID], + self::KEY_TYPE_CODE => $this->getMessageParts()[self::KEY_TYPE_CODE], + self::KEY_MESSAGE => $this->getMessageParts()[self::KEY_MESSAGE], ]; $processIdPadding = $this->getProcessIdPadding(); $processPathPadding = $this->getProcessPathPadding(); - $messageParts['processId'] = str_pad($messageParts['processId'], $processIdPadding, ' ', STR_PAD_LEFT); - $messageParts['typeCode'] = str_pad($messageParts['typeCode'], $processPathPadding, ' '); - $messageParts['level'] = str_pad($messageParts['level'], 12, ' '); + $paddedMessage[self::KEY_PROCESS_ID] = str_pad($paddedMessage[self::KEY_PROCESS_ID], + $processIdPadding, + ' ', + STR_PAD_LEFT + ); + $paddedMessage[self::KEY_TYPE_CODE] = str_pad($paddedMessage[self::KEY_TYPE_CODE], $processPathPadding, ' '); + $paddedMessage[self::KEY_LEVEL] = str_pad($paddedMessage[self::KEY_LEVEL], 12, ' '); - $message = implode(' | ', array_values($messageParts)); + $message = implode(' | ', array_values($paddedMessage)); $this->setFormattedMessage($message); return $this; @@ -118,4 +130,20 @@ protected function getProcessIdPadding() : int return $this->_read(self::PROP_PROCESS_ID_PADDING); } + public function setLogFormat(string $logFormat) + { + $this->_create(self::PROP_LOG_FORMAT, $logFormat); + + return $this; + } + + protected function getLogFormat() : string + { + return $this->_read(self::PROP_LOG_FORMAT); + } + + protected function hasLogFormat() : bool + { + return $this->_exists(self::PROP_LOG_FORMAT); + } } diff --git a/src/Process/Pool/LogFormatter.yml b/src/Process/Pool/LogFormatter.yml index 9c0d031a..218fe3e4 100644 --- a/src/Process/Pool/LogFormatter.yml +++ b/src/Process/Pool/LogFormatter.yml @@ -7,3 +7,4 @@ services: calls: - [setProcessIdPadding, ['%process.pool.logger.process_id_padding%']] - [setProcessPathPadding, ['%process.pool.logger.path_padding%']] + - [setLogFormat, ['%neighborhoods.kojo.environment.parameters.log_format%']] diff --git a/src/Process/Pool/LogFormatterInterface.php b/src/Process/Pool/LogFormatterInterface.php index ab6651f5..e0c843d8 100644 --- a/src/Process/Pool/LogFormatterInterface.php +++ b/src/Process/Pool/LogFormatterInterface.php @@ -24,4 +24,6 @@ public function setFormattedMessage(string $formattedMessage) : LogFormatterInte public function setProcessPathPadding(int $processPathPadding) : LogFormatterInterface; public function setProcessIdPadding(int $processIdPadding) : LogFormatterInterface; + + public function setLogFormat(string $logFormat); } From 33800e850b159c5c04d875704a841e2c0e28a0d6 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Tue, 26 Jun 2018 09:09:04 -0500 Subject: [PATCH 13/30] OPS-981 | remove type strings --- src/Process/Pool/LogFormatter.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index 895749c1..6dbb3c30 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -21,16 +21,13 @@ class LogFormatter implements LogFormatterInterface const KEY_TYPE_CODE = 'typeCode'; const KEY_MESSAGE = 'message'; - /** @var array */ protected $messageParts; - - /** @var string */ protected $formattedMessage; public function format() : LogFormatterInterface { - if ($this->hasLogFormat() && $this->getLogFormat() === 'pipes'){ + if ($this->hasLogFormat() && $this->getLogFormat() === 'pipes') { $this->formatPipes(); } else { $this->formatJson(); @@ -53,9 +50,9 @@ public function formatPipes() : LogFormatterInterface $processPathPadding = $this->getProcessPathPadding(); $paddedMessage[self::KEY_PROCESS_ID] = str_pad($paddedMessage[self::KEY_PROCESS_ID], - $processIdPadding, - ' ', - STR_PAD_LEFT + $processIdPadding, + ' ', + STR_PAD_LEFT ); $paddedMessage[self::KEY_TYPE_CODE] = str_pad($paddedMessage[self::KEY_TYPE_CODE], $processPathPadding, ' '); $paddedMessage[self::KEY_LEVEL] = str_pad($paddedMessage[self::KEY_LEVEL], 12, ' '); From 60ad29cf140891e332115e455460e7f2c0396ae9 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Tue, 26 Jun 2018 09:15:14 -0500 Subject: [PATCH 14/30] OPS-981 | add log_format_types --- src/Process/Pool/LogFormatter.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Process/Pool/LogFormatter.php b/src/Process/Pool/LogFormatter.php index 6dbb3c30..5818e24d 100644 --- a/src/Process/Pool/LogFormatter.php +++ b/src/Process/Pool/LogFormatter.php @@ -21,13 +21,15 @@ class LogFormatter implements LogFormatterInterface const KEY_TYPE_CODE = 'typeCode'; const KEY_MESSAGE = 'message'; + const LOG_FORMAT_PIPES = 'pipes'; + const LOG_FORMAT_JSON = 'json'; + protected $messageParts; protected $formattedMessage; - public function format() : LogFormatterInterface { - if ($this->hasLogFormat() && $this->getLogFormat() === 'pipes') { + if ($this->hasLogFormat() && $this->getLogFormat() === self::LOG_FORMAT_PIPES) { $this->formatPipes(); } else { $this->formatJson(); From bedbf1742028fc534ab6801488e048050b837d16 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Tue, 26 Jun 2018 09:16:48 -0500 Subject: [PATCH 15/30] OPS-981 | define strict_types=1 --- src/Process/Pool/LogFormatterInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Process/Pool/LogFormatterInterface.php b/src/Process/Pool/LogFormatterInterface.php index e0c843d8..69f61a16 100644 --- a/src/Process/Pool/LogFormatterInterface.php +++ b/src/Process/Pool/LogFormatterInterface.php @@ -1,5 +1,6 @@ Date: Wed, 27 Jun 2018 10:58:57 -0500 Subject: [PATCH 16/30] OPS-981 | We have a Logger Formatter not a logFormatter on our hands --- src/Process/Pool/LogFormatterInterface.php | 30 ------------------- .../Formatter.php} | 22 +++++++------- .../Formatter.yml} | 2 +- .../Pool/Logger/FormatterInterface.php | 30 +++++++++++++++++++ 4 files changed, 42 insertions(+), 42 deletions(-) delete mode 100644 src/Process/Pool/LogFormatterInterface.php rename src/Process/Pool/{LogFormatter.php => Logger/Formatter.php} (86%) rename src/Process/Pool/{LogFormatter.yml => Logger/Formatter.yml} (86%) create mode 100644 src/Process/Pool/Logger/FormatterInterface.php diff --git a/src/Process/Pool/LogFormatterInterface.php b/src/Process/Pool/LogFormatterInterface.php deleted file mode 100644 index 69f61a16..00000000 --- a/src/Process/Pool/LogFormatterInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -hasLogFormat() && $this->getLogFormat() === self::LOG_FORMAT_PIPES) { $this->formatPipes(); @@ -38,7 +38,7 @@ public function format() : LogFormatterInterface return $this; } - public function formatPipes() : LogFormatterInterface + public function formatPipes() : FormatterInterface { $paddedMessage = [ self::KEY_TIME => $this->getMessageParts()[self::KEY_TIME], @@ -65,7 +65,7 @@ public function formatPipes() : LogFormatterInterface return $this; } - public function formatJson() : LogFormatterInterface + public function formatJson() : FormatterInterface { $message = json_encode($this->getMessageParts()); $this->setFormattedMessage($message); @@ -76,13 +76,13 @@ public function formatJson() : LogFormatterInterface public function getMessageParts() : array { if ($this->messageParts === null) { - throw new \LogicException('LogFormatter messageParts has not been set.'); + throw new \LogicException('Formatter messageParts has not been set.'); } return $this->messageParts; } - public function setMessageParts(array $messageParts) : LogFormatterInterface + public function setMessageParts(array $messageParts) : FormatterInterface { $this->messageParts = $messageParts; @@ -92,20 +92,20 @@ public function setMessageParts(array $messageParts) : LogFormatterInterface public function getFormattedMessage() : string { if ($this->formattedMessage === null) { - throw new \LogicException('LogFormatter formattedMessage has not been set.'); + throw new \LogicException('Formatter formattedMessage has not been set.'); } return $this->formattedMessage; } - public function setFormattedMessage(string $formattedMessage) : LogFormatterInterface + public function setFormattedMessage(string $formattedMessage) : FormatterInterface { $this->formattedMessage = $formattedMessage; return $this; } - public function setProcessPathPadding(int $processPathPadding) : LogFormatterInterface + public function setProcessPathPadding(int $processPathPadding) : FormatterInterface { $this->_create(self::PROP_PROCESS_PATH_PADDING, $processPathPadding); @@ -117,7 +117,7 @@ protected function getProcessPathPadding() : int return $this->_read(self::PROP_PROCESS_PATH_PADDING); } - public function setProcessIdPadding(int $processIdPadding) : LogFormatterInterface + public function setProcessIdPadding(int $processIdPadding) : FormatterInterface { $this->_create(self::PROP_PROCESS_ID_PADDING, $processIdPadding); diff --git a/src/Process/Pool/LogFormatter.yml b/src/Process/Pool/Logger/Formatter.yml similarity index 86% rename from src/Process/Pool/LogFormatter.yml rename to src/Process/Pool/Logger/Formatter.yml index 218fe3e4..11cb45c9 100644 --- a/src/Process/Pool/LogFormatter.yml +++ b/src/Process/Pool/Logger/Formatter.yml @@ -3,7 +3,7 @@ parameters: process.pool.logger.path_padding: 80 services: neighborhoods.kojo.process.log_formatter: - class: Neighborhoods\Kojo\Process\Pool\LogFormatter + class: Neighborhoods\Kojo\Process\Pool\Logger\Formatter calls: - [setProcessIdPadding, ['%process.pool.logger.process_id_padding%']] - [setProcessPathPadding, ['%process.pool.logger.path_padding%']] diff --git a/src/Process/Pool/Logger/FormatterInterface.php b/src/Process/Pool/Logger/FormatterInterface.php new file mode 100644 index 00000000..0e3293b2 --- /dev/null +++ b/src/Process/Pool/Logger/FormatterInterface.php @@ -0,0 +1,30 @@ + Date: Wed, 27 Jun 2018 17:43:45 -0500 Subject: [PATCH 17/30] OPS-981 | refactor where formatter is called --- src/Process/Pool/Logger.php | 5 +++-- src/Process/Pool/LoggerInterface.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 578d3893..581a1ad8 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -3,6 +3,7 @@ namespace Neighborhoods\Kojo\Process\Pool; +use Neighborhoods\Kojo\Process\Pool\Logger\FormatterInterface; use Neighborhoods\Kojo\ProcessInterface; use Neighborhoods\Pylon\Data\Property\Defensive; use Neighborhoods\Pylon\Time; @@ -67,7 +68,7 @@ public function setIsEnabled(bool $isEnabled) : LoggerInterface return $this; } - public function getLogFormatter() : LogFormatterInterface + public function getLogFormatter() : FormatterInterface { if ($this->log_formatter === null) { throw new \LogicException('Logger log_formatter has not been set.'); @@ -76,7 +77,7 @@ public function getLogFormatter() : LogFormatterInterface return $this->log_formatter; } - public function setLogFormatter(LogFormatterInterface $log_formatter) : LoggerInterface + public function setLogFormatter(FormatterInterface $log_formatter) : LoggerInterface { if ($this->log_formatter !== null) { throw new \LogicException('Logger log_formatter already set.'); diff --git a/src/Process/Pool/LoggerInterface.php b/src/Process/Pool/LoggerInterface.php index 47117afd..76157bcc 100644 --- a/src/Process/Pool/LoggerInterface.php +++ b/src/Process/Pool/LoggerInterface.php @@ -3,6 +3,7 @@ namespace Neighborhoods\Kojo\Process\Pool; +use Neighborhoods\Kojo\Process\Pool\Logger\FormatterInterface; use Neighborhoods\Kojo\ProcessInterface; use Psr\Log; @@ -12,7 +13,7 @@ public function setProcess(ProcessInterface $process): LoggerInterface; public function setIsEnabled(bool $isEnabled): LoggerInterface; - public function getLogFormatter() : LogFormatterInterface; + public function getLogFormatter() : FormatterInterface; - public function setLogFormatter(LogFormatterInterface $log_formatter) : LoggerInterface; + public function setLogFormatter(FormatterInterface $log_formatter) : LoggerInterface; } From 8cf735a9a5c4622d5a9c3997241f7eae00db6994 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Wed, 27 Jun 2018 17:50:36 -0500 Subject: [PATCH 18/30] OPS-981 | namespace the params in the formatter --- src/Process/Pool/Logger/Formatter.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Process/Pool/Logger/Formatter.yml b/src/Process/Pool/Logger/Formatter.yml index 11cb45c9..69c60cfa 100644 --- a/src/Process/Pool/Logger/Formatter.yml +++ b/src/Process/Pool/Logger/Formatter.yml @@ -1,10 +1,11 @@ parameters: - process.pool.logger.process_id_padding: 6 - process.pool.logger.path_padding: 80 + process.pool.logger.formatter.process_id_padding: 6 + process.pool.logger.formatter.path_padding: 80 + process.pool.logger.formatter.log_format: 'json' services: neighborhoods.kojo.process.log_formatter: class: Neighborhoods\Kojo\Process\Pool\Logger\Formatter calls: - - [setProcessIdPadding, ['%process.pool.logger.process_id_padding%']] - - [setProcessPathPadding, ['%process.pool.logger.path_padding%']] - - [setLogFormat, ['%neighborhoods.kojo.environment.parameters.log_format%']] + - [setProcessIdPadding, ['%process.pool.logger.formatter.process_id_padding%']] + - [setProcessPathPadding, ['%process.pool.logger.formatter.path_padding%']] + - [setLogFormat, ['%process.pool.logger.formatter.log_format%']] From b94cb2ff48d5bc62ddc07dc22f24fd4a6db56626 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Thu, 28 Jun 2018 12:26:15 -0500 Subject: [PATCH 19/30] OPS-981 | create a Logger Message DAO --- src/Process/Pool/Logger.php | 16 +-- src/Process/Pool/Logger.yml | 1 + src/Process/Pool/Logger/Formatter.php | 46 +++--- .../Pool/Logger/FormatterInterface.php | 4 +- src/Process/Pool/Logger/Message.php | 131 ++++++++++++++++++ src/Process/Pool/Logger/Message.yml | 3 + .../Pool/Logger/Message/AwareTrait.php | 46 ++++++ src/Process/Pool/Logger/Message/Factory.php | 19 +++ src/Process/Pool/Logger/Message/Factory.yml | 5 + .../Logger/Message/Factory/AwareTrait.php | 46 ++++++ .../Pool/Logger/Message/FactoryInterface.php | 12 ++ src/Process/Pool/Logger/MessageInterface.php | 29 ++++ 12 files changed, 320 insertions(+), 38 deletions(-) create mode 100644 src/Process/Pool/Logger/Message.php create mode 100644 src/Process/Pool/Logger/Message.yml create mode 100644 src/Process/Pool/Logger/Message/AwareTrait.php create mode 100644 src/Process/Pool/Logger/Message/Factory.php create mode 100644 src/Process/Pool/Logger/Message/Factory.yml create mode 100644 src/Process/Pool/Logger/Message/Factory/AwareTrait.php create mode 100644 src/Process/Pool/Logger/Message/FactoryInterface.php create mode 100644 src/Process/Pool/Logger/MessageInterface.php diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 581a1ad8..4db0e8df 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -12,6 +12,7 @@ class Logger extends Log\AbstractLogger implements LoggerInterface { use Time\AwareTrait; + use Logger\Message\Factory\AwareTrait; use Defensive\AwareTrait; const PROP_IS_ENABLED = 'is_enabled'; @@ -41,15 +42,14 @@ public function log($level, $message, array $context = []) $referenceTime = $this->_getTime()->getUnixReferenceTimeNow(); - $messageParts = [ - 'time' => $referenceTime, - 'level' => $level, - 'processId' => $processId, - 'typeCode' => $this->_getProcess()->getPath(), - 'message' => $message, - ]; + $logMessage = $this->getProcessPoolLoggerMessageFactory()->create(); + $logMessage->setTime($referenceTime); + $logMessage->setLevel($level); + $logMessage->setProcessId($processId); + $logMessage->setTypeCode($this->_getProcess()->getPath()); + $logMessage->setMessage($message); - $this->getLogFormatter()->setMessageParts($messageParts)->format(); + $this->getLogFormatter()->setMessage($logMessage)->format(); fwrite(STDOUT, $this->getLogFormatter()->getFormattedMessage() . "\n"); } diff --git a/src/Process/Pool/Logger.yml b/src/Process/Pool/Logger.yml index 3ae2dcf5..0842ab8a 100644 --- a/src/Process/Pool/Logger.yml +++ b/src/Process/Pool/Logger.yml @@ -7,5 +7,6 @@ services: - [setIsEnabled, ['%process.pool.logger.is_enabled%']] - [setTime, ['@neighborhoods.pylon.time']] - [setLogFormatter, ['@neighborhoods.kojo.process.log_formatter']] + - [setProcessPoolLoggerMessageFactory, ['@neighborhoods.kojo.process.pool.logger.message.factory']] process.pool.logger: alias: neighborhoods.kojo.process.pool.logger diff --git a/src/Process/Pool/Logger/Formatter.php b/src/Process/Pool/Logger/Formatter.php index 52823074..7f526959 100644 --- a/src/Process/Pool/Logger/Formatter.php +++ b/src/Process/Pool/Logger/Formatter.php @@ -24,7 +24,7 @@ class Formatter implements FormatterInterface const LOG_FORMAT_PIPES = 'pipes'; const LOG_FORMAT_JSON = 'json'; - protected $messageParts; + protected $message; protected $formattedMessage; public function format() : FormatterInterface @@ -40,51 +40,41 @@ public function format() : FormatterInterface public function formatPipes() : FormatterInterface { - $paddedMessage = [ - self::KEY_TIME => $this->getMessageParts()[self::KEY_TIME], - self::KEY_LEVEL => $this->getMessageParts()[self::KEY_LEVEL], - self::KEY_PROCESS_ID => $this->getMessageParts()[self::KEY_PROCESS_ID], - self::KEY_TYPE_CODE => $this->getMessageParts()[self::KEY_TYPE_CODE], - self::KEY_MESSAGE => $this->getMessageParts()[self::KEY_MESSAGE], - ]; - - $processIdPadding = $this->getProcessIdPadding(); - $processPathPadding = $this->getProcessPathPadding(); - - $paddedMessage[self::KEY_PROCESS_ID] = str_pad($paddedMessage[self::KEY_PROCESS_ID], - $processIdPadding, - ' ', - STR_PAD_LEFT - ); - $paddedMessage[self::KEY_TYPE_CODE] = str_pad($paddedMessage[self::KEY_TYPE_CODE], $processPathPadding, ' '); - $paddedMessage[self::KEY_LEVEL] = str_pad($paddedMessage[self::KEY_LEVEL], 12, ' '); - - $message = implode(' | ', array_values($paddedMessage)); - $this->setFormattedMessage($message); + $message = $this->getMessage(); + + $processIdPaddingLength = $this->getProcessIdPadding(); + $processPathPaddingLength = $this->getProcessPathPadding(); + + $processID = str_pad($message->getProcessId(), $processIdPaddingLength, ' ', STR_PAD_LEFT); + $typeCode = str_pad($message->getTypeCode(), $processPathPaddingLength, ' '); + $level = str_pad($message->getLevel(), 12, ' '); + + $pipeDelimitedMessage = implode(' | ', [$message->getTime(), $level, $processID, $typeCode]); + $this->setFormattedMessage($pipeDelimitedMessage); return $this; } public function formatJson() : FormatterInterface { - $message = json_encode($this->getMessageParts()); + $message = json_encode($this->getMessage()); $this->setFormattedMessage($message); return $this; } - public function getMessageParts() : array + public function getMessage() : MessageInterface { - if ($this->messageParts === null) { + if ($this->message === null) { throw new \LogicException('Formatter messageParts has not been set.'); } - return $this->messageParts; + return $this->message; } - public function setMessageParts(array $messageParts) : FormatterInterface + public function setMessage(MessageInterface $message) : FormatterInterface { - $this->messageParts = $messageParts; + $this->message = $message; return $this; } diff --git a/src/Process/Pool/Logger/FormatterInterface.php b/src/Process/Pool/Logger/FormatterInterface.php index 0e3293b2..888f99a6 100644 --- a/src/Process/Pool/Logger/FormatterInterface.php +++ b/src/Process/Pool/Logger/FormatterInterface.php @@ -14,9 +14,9 @@ public function formatPipes() : FormatterInterface; public function formatJson() : FormatterInterface; - public function getMessageParts() : array; + public function getMessage() : MessageInterface; - public function setMessageParts(array $messageParts) : FormatterInterface; + public function setMessage(MessageInterface $message) : FormatterInterface; public function getFormattedMessage() : string; diff --git a/src/Process/Pool/Logger/Message.php b/src/Process/Pool/Logger/Message.php new file mode 100644 index 00000000..066c862b --- /dev/null +++ b/src/Process/Pool/Logger/Message.php @@ -0,0 +1,131 @@ + $this->getTime(), + self::KEY_LEVEL => $this->getLevel(), + self::KEY_PROCESS_ID => $this->getProcessId(), + self::KEY_TYPE_CODE => $this->getTypeCode(), + self::KEY_MESSAGE => $this->getMessage(), + ]; + } + + public function getTime() : string + { + if ($this->time === null) { + throw new \LogicException('Message ' . self::KEY_TIME . ' has not been set.'); + } + + return $this->time; + } + + public function setTime(string $time) : MessageInterface + { + if ($this->time !== null) { + throw new \LogicException('Message ' . self::KEY_TIME . ' already set.'); + } + + $this->time = $time; + + return $this; + } + + public function getLevel() : string + { + if ($this->level === null) { + throw new \LogicException('Message ' . self::KEY_LEVEL . ' has not been set.'); + } + + return $this->level; + } + + public function setLevel(string $level) : MessageInterface + { + if ($this->level !== null) { + throw new \LogicException('Message ' . self::KEY_LEVEL . ' already set.'); + } + + $this->level = $level; + + return $this; + } + + public function getProcessId() : string + { + if ($this->process_id === null) { + throw new \LogicException('Message ' . self::KEY_PROCESS_ID . ' has not been set.'); + } + + return $this->process_id; + } + + public function setProcessId(string $process_id) : MessageInterface + { + if ($this->process_id !== null) { + throw new \LogicException('Message ' . self::KEY_PROCESS_ID . ' already set.'); + } + + $this->process_id = $process_id; + + return $this; + } + + public function getTypeCode() : string + { + if ($this->type_code === null) { + throw new \LogicException('Message ' . self::KEY_TYPE_CODE . ' has not been set.'); + } + + return $this->type_code; + } + + public function setTypeCode(string $type_code) : MessageInterface + { + if ($this->type_code !== null) { + throw new \LogicException('Message ' . self::KEY_TYPE_CODE . ' already set.'); + } + + $this->type_code = $type_code; + + return $this; + } + + public function getMessage() : string + { + if ($this->message === null) { + throw new \LogicException('Message ' . self::KEY_MESSAGE . ' has not been set.'); + } + + return $this->message; + } + + public function setMessage(string $message) : MessageInterface + { + if ($this->message !== null) { + throw new \LogicException('Message ' . self::KEY_MESSAGE . ' already set.'); + } + + $this->message = $message; + + return $this; + } +} diff --git a/src/Process/Pool/Logger/Message.yml b/src/Process/Pool/Logger/Message.yml new file mode 100644 index 00000000..8e84b2d4 --- /dev/null +++ b/src/Process/Pool/Logger/Message.yml @@ -0,0 +1,3 @@ +services: + neighborhoods.kojo.process.pool.logger.message: + class: Neighborhoods\Kojo\Process\Pool\Logger\Message diff --git a/src/Process/Pool/Logger/Message/AwareTrait.php b/src/Process/Pool/Logger/Message/AwareTrait.php new file mode 100644 index 00000000..057ab993 --- /dev/null +++ b/src/Process/Pool/Logger/Message/AwareTrait.php @@ -0,0 +1,46 @@ +hasProcessPoolLoggerMessage(), + new \LogicException('NeighborhoodsKojoProcessPoolLoggerMessage is already set.') + ); + $this->NeighborhoodsKojoProcessPoolLoggerMessage = $processPoolLoggerMessage; + + return $this; + } + + protected function getProcessPoolLoggerMessage() : MessageInterface + { + assert($this->hasProcessPoolLoggerMessage(), + new \LogicException('NeighborhoodsKojoProcessPoolLoggerMessage is not set.') + ); + + return $this->NeighborhoodsKojoProcessPoolLoggerMessage; + } + + protected function hasProcessPoolLoggerMessage() : bool + { + return isset($this->NeighborhoodsKojoProcessPoolLoggerMessage); + } + + protected function unsetProcessPoolLoggerMessage() : self + { + assert($this->hasProcessPoolLoggerMessage(), + new \LogicException('NeighborhoodsKojoProcessPoolLoggerMessage is not set.') + ); + unset($this->NeighborhoodsKojoProcessPoolLoggerMessage); + + return $this; + } +} diff --git a/src/Process/Pool/Logger/Message/Factory.php b/src/Process/Pool/Logger/Message/Factory.php new file mode 100644 index 00000000..a28b7809 --- /dev/null +++ b/src/Process/Pool/Logger/Message/Factory.php @@ -0,0 +1,19 @@ +getProcessPoolLoggerMessage(); + } +} diff --git a/src/Process/Pool/Logger/Message/Factory.yml b/src/Process/Pool/Logger/Message/Factory.yml new file mode 100644 index 00000000..ffcba4ed --- /dev/null +++ b/src/Process/Pool/Logger/Message/Factory.yml @@ -0,0 +1,5 @@ +services: + neighborhoods.kojo.process.pool.logger.message.factory: + class: Neighborhoods\Kojo\Process\Pool\Logger\Message\Factory + calls: + - [setProcessPoolLoggerMessage, ['@neighborhoods.kojo.process.pool.logger.message']] diff --git a/src/Process/Pool/Logger/Message/Factory/AwareTrait.php b/src/Process/Pool/Logger/Message/Factory/AwareTrait.php new file mode 100644 index 00000000..e30a3141 --- /dev/null +++ b/src/Process/Pool/Logger/Message/Factory/AwareTrait.php @@ -0,0 +1,46 @@ +hasProcessPoolLoggerMessageFactory(), + new \LogicException('NeighborhoodsKojoProcessPoolLoggerMessageFactory is already set.') + ); + $this->NeighborhoodsKojoProcessPoolLoggerMessageFactory = $processPoolLoggerMessageFactory; + + return $this; + } + + protected function getProcessPoolLoggerMessageFactory() : FactoryInterface + { + assert($this->hasProcessPoolLoggerMessageFactory(), + new \LogicException('NeighborhoodsKojoProcessPoolLoggerMessageFactory is not set.') + ); + + return $this->NeighborhoodsKojoProcessPoolLoggerMessageFactory; + } + + protected function hasProcessPoolLoggerMessageFactory() : bool + { + return isset($this->NeighborhoodsKojoProcessPoolLoggerMessageFactory); + } + + protected function unsetProcessPoolLoggerMessageFactory() : self + { + assert($this->hasProcessPoolLoggerMessageFactory(), + new \LogicException('NeighborhoodsKojoProcessPoolLoggerMessageFactory is not set.') + ); + unset($this->NeighborhoodsKojoProcessPoolLoggerMessageFactory); + + return $this; + } +} diff --git a/src/Process/Pool/Logger/Message/FactoryInterface.php b/src/Process/Pool/Logger/Message/FactoryInterface.php new file mode 100644 index 00000000..6482630e --- /dev/null +++ b/src/Process/Pool/Logger/Message/FactoryInterface.php @@ -0,0 +1,12 @@ + Date: Thu, 28 Jun 2018 13:34:35 -0500 Subject: [PATCH 20/30] OPS-981 | pass the message contents to the pipes formatted message --- src/Process/Pool/Logger/Formatter.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Process/Pool/Logger/Formatter.php b/src/Process/Pool/Logger/Formatter.php index 7f526959..414ed1c8 100644 --- a/src/Process/Pool/Logger/Formatter.php +++ b/src/Process/Pool/Logger/Formatter.php @@ -40,16 +40,16 @@ public function format() : FormatterInterface public function formatPipes() : FormatterInterface { - $message = $this->getMessage(); + $logMessage = $this->getMessage(); $processIdPaddingLength = $this->getProcessIdPadding(); $processPathPaddingLength = $this->getProcessPathPadding(); - $processID = str_pad($message->getProcessId(), $processIdPaddingLength, ' ', STR_PAD_LEFT); - $typeCode = str_pad($message->getTypeCode(), $processPathPaddingLength, ' '); - $level = str_pad($message->getLevel(), 12, ' '); + $processID = str_pad($logMessage->getProcessId(), $processIdPaddingLength, ' ', STR_PAD_LEFT); + $typeCode = str_pad($logMessage->getTypeCode(), $processPathPaddingLength, ' '); + $level = str_pad($logMessage->getLevel(), 12, ' '); - $pipeDelimitedMessage = implode(' | ', [$message->getTime(), $level, $processID, $typeCode]); + $pipeDelimitedMessage = implode(' | ', [$logMessage->getTime(), $level, $processID, $typeCode, $logMessage->getMessage()]); $this->setFormattedMessage($pipeDelimitedMessage); return $this; @@ -57,8 +57,8 @@ public function formatPipes() : FormatterInterface public function formatJson() : FormatterInterface { - $message = json_encode($this->getMessage()); - $this->setFormattedMessage($message); + $logMessage = json_encode($this->getMessage()); + $this->setFormattedMessage($logMessage); return $this; } From 9e4df4883b6f1846916b996fbcee5c855ac96631 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Thu, 28 Jun 2018 14:25:26 -0500 Subject: [PATCH 21/30] OPS-981 | get and return formatted message --- src/Process/Pool/Logger.php | 3 +-- src/Process/Pool/Logger/Formatter.php | 24 +++++++------------ .../Pool/Logger/FormatterInterface.php | 15 +----------- 3 files changed, 11 insertions(+), 31 deletions(-) diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 4db0e8df..53b43628 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -49,8 +49,7 @@ public function log($level, $message, array $context = []) $logMessage->setTypeCode($this->_getProcess()->getPath()); $logMessage->setMessage($message); - $this->getLogFormatter()->setMessage($logMessage)->format(); - fwrite(STDOUT, $this->getLogFormatter()->getFormattedMessage() . "\n"); + fwrite(STDOUT, $this->getLogFormatter()->getFormattedMessage($logMessage) . "\n"); } return; diff --git a/src/Process/Pool/Logger/Formatter.php b/src/Process/Pool/Logger/Formatter.php index 414ed1c8..c95a39d4 100644 --- a/src/Process/Pool/Logger/Formatter.php +++ b/src/Process/Pool/Logger/Formatter.php @@ -27,18 +27,20 @@ class Formatter implements FormatterInterface protected $message; protected $formattedMessage; - public function format() : FormatterInterface + public function getFormattedMessage(MessageInterface $message) : string { + $this->setMessage($message); + if ($this->hasLogFormat() && $this->getLogFormat() === self::LOG_FORMAT_PIPES) { $this->formatPipes(); } else { $this->formatJson(); } - return $this; + return $this->formattedMessage; } - public function formatPipes() : FormatterInterface + protected function formatPipes() : FormatterInterface { $logMessage = $this->getMessage(); @@ -55,7 +57,7 @@ public function formatPipes() : FormatterInterface return $this; } - public function formatJson() : FormatterInterface + protected function formatJson() : FormatterInterface { $logMessage = json_encode($this->getMessage()); $this->setFormattedMessage($logMessage); @@ -63,7 +65,7 @@ public function formatJson() : FormatterInterface return $this; } - public function getMessage() : MessageInterface + protected function getMessage() : MessageInterface { if ($this->message === null) { throw new \LogicException('Formatter messageParts has not been set.'); @@ -72,23 +74,15 @@ public function getMessage() : MessageInterface return $this->message; } - public function setMessage(MessageInterface $message) : FormatterInterface + protected function setMessage(MessageInterface $message) : FormatterInterface { $this->message = $message; return $this; } - public function getFormattedMessage() : string - { - if ($this->formattedMessage === null) { - throw new \LogicException('Formatter formattedMessage has not been set.'); - } - - return $this->formattedMessage; - } - public function setFormattedMessage(string $formattedMessage) : FormatterInterface + protected function setFormattedMessage(string $formattedMessage) : FormatterInterface { $this->formattedMessage = $formattedMessage; diff --git a/src/Process/Pool/Logger/FormatterInterface.php b/src/Process/Pool/Logger/FormatterInterface.php index 888f99a6..f5fc4f4c 100644 --- a/src/Process/Pool/Logger/FormatterInterface.php +++ b/src/Process/Pool/Logger/FormatterInterface.php @@ -7,20 +7,7 @@ interface FormatterInterface { - - public function format() : FormatterInterface; - - public function formatPipes() : FormatterInterface; - - public function formatJson() : FormatterInterface; - - public function getMessage() : MessageInterface; - - public function setMessage(MessageInterface $message) : FormatterInterface; - - public function getFormattedMessage() : string; - - public function setFormattedMessage(string $formattedMessage) : FormatterInterface; + public function getFormattedMessage(MessageInterface $message) : string; public function setProcessPathPadding(int $processPathPadding) : FormatterInterface; From 23e42c10e942244049ce637079caefee32258810 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Fri, 29 Jun 2018 07:46:22 -0500 Subject: [PATCH 22/30] OPS-981 | Skip setting the message object on the formatter and just pass it to methods --- src/Process/Pool/Logger/Formatter.php | 63 ++++----------------------- 1 file changed, 9 insertions(+), 54 deletions(-) diff --git a/src/Process/Pool/Logger/Formatter.php b/src/Process/Pool/Logger/Formatter.php index c95a39d4..62a67049 100644 --- a/src/Process/Pool/Logger/Formatter.php +++ b/src/Process/Pool/Logger/Formatter.php @@ -15,78 +15,33 @@ class Formatter implements FormatterInterface const PROP_PROCESS_ID_PADDING = 'process_id_padding'; const PROP_LOG_FORMAT = 'log_format'; - const KEY_TIME = 'time'; - const KEY_LEVEL = 'level'; - const KEY_PROCESS_ID = 'processId'; - const KEY_TYPE_CODE = 'typeCode'; - const KEY_MESSAGE = 'message'; - const LOG_FORMAT_PIPES = 'pipes'; const LOG_FORMAT_JSON = 'json'; - protected $message; - protected $formattedMessage; - public function getFormattedMessage(MessageInterface $message) : string { - $this->setMessage($message); - if ($this->hasLogFormat() && $this->getLogFormat() === self::LOG_FORMAT_PIPES) { - $this->formatPipes(); + return $this->formatPipes($message); } else { - $this->formatJson(); + return $this->formatJson($message); } - - return $this->formattedMessage; } - protected function formatPipes() : FormatterInterface + protected function formatPipes(MessageInterface $message) : string { - $logMessage = $this->getMessage(); - $processIdPaddingLength = $this->getProcessIdPadding(); $processPathPaddingLength = $this->getProcessPathPadding(); - $processID = str_pad($logMessage->getProcessId(), $processIdPaddingLength, ' ', STR_PAD_LEFT); - $typeCode = str_pad($logMessage->getTypeCode(), $processPathPaddingLength, ' '); - $level = str_pad($logMessage->getLevel(), 12, ' '); - - $pipeDelimitedMessage = implode(' | ', [$logMessage->getTime(), $level, $processID, $typeCode, $logMessage->getMessage()]); - $this->setFormattedMessage($pipeDelimitedMessage); + $processID = str_pad($message->getProcessId(), $processIdPaddingLength, ' ', STR_PAD_LEFT); + $typeCode = str_pad($message->getTypeCode(), $processPathPaddingLength, ' '); + $level = str_pad($message->getLevel(), 12, ' '); - return $this; + return implode(' | ', [$message->getTime(), $level, $processID, $typeCode, $message->getMessage()]); } - protected function formatJson() : FormatterInterface + protected function formatJson(MessageInterface $message) : string { - $logMessage = json_encode($this->getMessage()); - $this->setFormattedMessage($logMessage); - - return $this; - } - - protected function getMessage() : MessageInterface - { - if ($this->message === null) { - throw new \LogicException('Formatter messageParts has not been set.'); - } - - return $this->message; - } - - protected function setMessage(MessageInterface $message) : FormatterInterface - { - $this->message = $message; - - return $this; - } - - - protected function setFormattedMessage(string $formattedMessage) : FormatterInterface - { - $this->formattedMessage = $formattedMessage; - - return $this; + return json_encode($message); } public function setProcessPathPadding(int $processPathPadding) : FormatterInterface From 96d3cdf2d240a99ab611b91dfe3febf7ae9f649a Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Fri, 29 Jun 2018 09:12:27 -0500 Subject: [PATCH 23/30] OPS-981 | remove vestigial parameter that is now part of the formatter --- src/Environment/Parameters.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Environment/Parameters.yml b/src/Environment/Parameters.yml index d9fe967d..ae01ec01 100644 --- a/src/Environment/Parameters.yml +++ b/src/Environment/Parameters.yml @@ -6,4 +6,3 @@ parameters: neighborhoods.kojo.environment.parameters.database_adapter: '' neighborhoods.kojo.environment.parameters.database_host: '' neighborhoods.kojo.environment.parameters.database_name: '' - neighborhoods.kojo.environment.parameters.log_format: '' From 41df82b1ac0f5af037ad35d853570cf95fb3d12f Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Fri, 29 Jun 2018 09:14:13 -0500 Subject: [PATCH 24/30] OPS-981 | use !php/const to link yaml with the constant in the code --- src/Process/Pool/Logger/Formatter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Process/Pool/Logger/Formatter.yml b/src/Process/Pool/Logger/Formatter.yml index 69c60cfa..ffcc8b5b 100644 --- a/src/Process/Pool/Logger/Formatter.yml +++ b/src/Process/Pool/Logger/Formatter.yml @@ -1,7 +1,7 @@ parameters: process.pool.logger.formatter.process_id_padding: 6 process.pool.logger.formatter.path_padding: 80 - process.pool.logger.formatter.log_format: 'json' + process.pool.logger.formatter.log_format: !php/const \Neighborhoods\Kojo\Process\Pool\Logger\Formatter::LOG_FORMAT_JSON services: neighborhoods.kojo.process.log_formatter: class: Neighborhoods\Kojo\Process\Pool\Logger\Formatter From 97c87c9cc4280bfb62ac23407af4934023370ae7 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Sun, 1 Jul 2018 13:54:49 -0500 Subject: [PATCH 25/30] Improve logger output control --- .../Command/Process/Pool/Server/Start.php | 2 +- src/Console/CommandAbstract.php | 22 +++++-- src/Process/Pool/Logger.php | 60 ++++++++++++------- src/Process/Pool/Logger.yml | 12 +++- src/Process/Pool/Logger/Formatter.php | 4 +- src/Process/Pool/Logger/Message.php | 40 ++++++------- src/Process/Pool/Logger/MessageInterface.php | 4 +- src/Process/Pool/LoggerInterface.php | 2 + src/Process/Pool/Server.php | 5 +- 9 files changed, 98 insertions(+), 53 deletions(-) diff --git a/src/Console/Command/Process/Pool/Server/Start.php b/src/Console/Command/Process/Pool/Server/Start.php index fed141c3..3cf35e72 100644 --- a/src/Console/Command/Process/Pool/Server/Start.php +++ b/src/Console/Command/Process/Pool/Server/Start.php @@ -33,7 +33,7 @@ protected function _configure(): CommandAbstract public function _execute(): CommandAbstract { $arguments = [self::OPT_RUN_SERVER]; - $arguments[] = self::OPT_YSDP . $this->_getInput()->getArgument(self::ARG_SERVICES_YML_FILE_PATH); + $arguments[] = self::OPT_YSDP . $this->_getInput()->getArgument(self::ARG_SERVICES_YML_ROOT_DIRECTORY_PATH); foreach ($this->_getInput()->getOption(self::OPT_SERVICES_YML_DIRECTORY_PATH) as $servicesYmlFilePath) { $arguments[] = self::OPT_YSDP . $servicesYmlFilePath; } diff --git a/src/Console/CommandAbstract.php b/src/Console/CommandAbstract.php index 707161e2..a4647f0a 100644 --- a/src/Console/CommandAbstract.php +++ b/src/Console/CommandAbstract.php @@ -5,6 +5,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Neighborhoods\Pylon\Data\Property\Defensive; use Symfony\Component\Console\Input\InputArgument; @@ -12,8 +13,10 @@ abstract class CommandAbstract extends Command { use Defensive\AwareTrait; - const ARG_SERVICES_YML_FILE_PATH = 'services_yml_file_path'; - const SPLASH_ART = [ + public const ARG_SERVICES_YML_ROOT_DIRECTORY_PATH = 'services_yml_root_directory_path'; + public const OPT_ENABLE_SPLASH_ART = 'enable-splash-art'; + public const OPT_ESA = 'esa'; + public const SPLASH_ART = [ '+------------------------------+', '| ⚡ Neighborhoods Kōjō ⚡ |', '| |', @@ -26,9 +29,16 @@ abstract class CommandAbstract extends Command public function configure() { $this->addArgument( - self::ARG_SERVICES_YML_FILE_PATH, + self::ARG_SERVICES_YML_ROOT_DIRECTORY_PATH, InputArgument::REQUIRED, - 'The path to the YML services file for the client application.' + 'The path to the YML services root directory for the client application.' + ); + + $this->addOption( + self::OPT_ENABLE_SPLASH_ART, + self::OPT_ESA, + InputOption::VALUE_NONE, + 'Enables the splash art to be written to STDOUT.' ); $this->_configure(); @@ -42,7 +52,9 @@ public function execute(InputInterface $input, OutputInterface $output) { $this->_setInput($input); $this->_setOutput($output); - $this->_writeSplashArt(); + if ($this->_getInput()->getOption(self::OPT_ENABLE_SPLASH_ART)) { + $this->_writeSplashArt(); + } $this->_execute(); return $this; diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 53b43628..3185e5d2 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -17,15 +17,16 @@ class Logger extends Log\AbstractLogger implements LoggerInterface const PROP_IS_ENABLED = 'is_enabled'; protected $log_formatter; + protected $level_filter_mask; - public function setProcess(ProcessInterface $process) : LoggerInterface + public function setProcess(ProcessInterface $process): LoggerInterface { $this->_createOrUpdate(ProcessInterface::class, $process); return $this; } - protected function _getProcess() : ProcessInterface + protected function _getProcess(): ProcessInterface { return $this->_read(ProcessInterface::class); } @@ -33,41 +34,60 @@ protected function _getProcess() : ProcessInterface public function log($level, $message, array $context = []) { if ($this->_isEnabled() === true) { - - if ($this->_exists(ProcessInterface::class)) { - $processId = (string)$this->_getProcess()->getProcessId(); - } else { - $processId = '?'; + if ($this->getLevelFilterMask()[$level] === false) { + if ($this->_exists(ProcessInterface::class)) { + $processId = (string)$this->_getProcess()->getProcessId(); + } else { + $processId = '?'; + } + + $referenceTime = $this->_getTime()->getUnixReferenceTimeNow(); + $logMessage = $this->getProcessPoolLoggerMessageFactory()->create(); + $logMessage->setTime($referenceTime); + $logMessage->setLevel($level); + $logMessage->setProcessId($processId); + $logMessage->setProcessPath($this->_getProcess()->getPath()); + $logMessage->setMessage($message); + fwrite(STDOUT, $this->getLogFormatter()->getFormattedMessage($logMessage) . "\n"); } + } - $referenceTime = $this->_getTime()->getUnixReferenceTimeNow(); + return; + } - $logMessage = $this->getProcessPoolLoggerMessageFactory()->create(); - $logMessage->setTime($referenceTime); - $logMessage->setLevel($level); - $logMessage->setProcessId($processId); - $logMessage->setTypeCode($this->_getProcess()->getPath()); - $logMessage->setMessage($message); + public function setLevelFilterMask(array $level_filter_mask): LoggerInterface + { + if ($this->level_filter_mask === null) { + $this->level_filter_mask = $level_filter_mask; + } else { + throw new \LogicException('Logger level_filter_mask is already set.'); + } - fwrite(STDOUT, $this->getLogFormatter()->getFormattedMessage($logMessage) . "\n"); + return $this; + } + + protected function getLevelFilterMask(): array + { + if ($this->level_filter_mask === null) { + $this->level_filter_mask = []; } - return; + return $this->level_filter_mask; } - protected function _isEnabled() : bool + protected function _isEnabled(): bool { return $this->_read(self::PROP_IS_ENABLED); } - public function setIsEnabled(bool $isEnabled) : LoggerInterface + public function setIsEnabled(bool $isEnabled): LoggerInterface { $this->_create(self::PROP_IS_ENABLED, $isEnabled); return $this; } - public function getLogFormatter() : FormatterInterface + public function getLogFormatter(): FormatterInterface { if ($this->log_formatter === null) { throw new \LogicException('Logger log_formatter has not been set.'); @@ -76,7 +96,7 @@ public function getLogFormatter() : FormatterInterface return $this->log_formatter; } - public function setLogFormatter(FormatterInterface $log_formatter) : LoggerInterface + public function setLogFormatter(FormatterInterface $log_formatter): LoggerInterface { if ($this->log_formatter !== null) { throw new \LogicException('Logger log_formatter already set.'); diff --git a/src/Process/Pool/Logger.yml b/src/Process/Pool/Logger.yml index 0842ab8a..02dcc027 100644 --- a/src/Process/Pool/Logger.yml +++ b/src/Process/Pool/Logger.yml @@ -1,5 +1,14 @@ parameters: process.pool.logger.is_enabled: true + neighborhoods.kojo.process.pool.logger.level_filter_mask: + !php/const \Psr\Log\LogLevel::EMERGENCY: false + !php/const \Psr\Log\LogLevel::ALERT: false + !php/const \Psr\Log\LogLevel::CRITICAL: false + !php/const \Psr\Log\LogLevel::ERROR: false + !php/const \Psr\Log\LogLevel::WARNING: false + !php/const \Psr\Log\LogLevel::NOTICE: false + !php/const \Psr\Log\LogLevel::INFO: false + !php/const \Psr\Log\LogLevel::DEBUG: true services: neighborhoods.kojo.process.pool.logger: class: Neighborhoods\Kojo\Process\Pool\Logger @@ -8,5 +17,6 @@ services: - [setTime, ['@neighborhoods.pylon.time']] - [setLogFormatter, ['@neighborhoods.kojo.process.log_formatter']] - [setProcessPoolLoggerMessageFactory, ['@neighborhoods.kojo.process.pool.logger.message.factory']] + - [setLevelFilterMask, ['%neighborhoods.kojo.process.pool.logger.level_filter_mask%']] process.pool.logger: - alias: neighborhoods.kojo.process.pool.logger + alias: neighborhoods.kojo.process.pool.logger \ No newline at end of file diff --git a/src/Process/Pool/Logger/Formatter.php b/src/Process/Pool/Logger/Formatter.php index 62a67049..501cb408 100644 --- a/src/Process/Pool/Logger/Formatter.php +++ b/src/Process/Pool/Logger/Formatter.php @@ -33,10 +33,10 @@ protected function formatPipes(MessageInterface $message) : string $processPathPaddingLength = $this->getProcessPathPadding(); $processID = str_pad($message->getProcessId(), $processIdPaddingLength, ' ', STR_PAD_LEFT); - $typeCode = str_pad($message->getTypeCode(), $processPathPaddingLength, ' '); + $processPath = str_pad($message->getProcessPath(), $processPathPaddingLength, ' '); $level = str_pad($message->getLevel(), 12, ' '); - return implode(' | ', [$message->getTime(), $level, $processID, $typeCode, $message->getMessage()]); + return implode(' | ', [$message->getTime(), $level, $processID, $processPath, $message->getMessage()]); } protected function formatJson(MessageInterface $message) : string diff --git a/src/Process/Pool/Logger/Message.php b/src/Process/Pool/Logger/Message.php index 066c862b..c0889f8f 100644 --- a/src/Process/Pool/Logger/Message.php +++ b/src/Process/Pool/Logger/Message.php @@ -9,27 +9,27 @@ class Message implements MessageInterface, \JsonSerializable const KEY_TIME = 'time'; const KEY_LEVEL = 'level'; const KEY_PROCESS_ID = 'process_id'; - const KEY_TYPE_CODE = 'type_code'; + const KEY_PROCESS_PATH = 'process_path'; const KEY_MESSAGE = 'message'; protected $time; protected $level; protected $process_id; - protected $type_code; + protected $process_path; protected $message; - public function jsonSerialize() : array + public function jsonSerialize(): array { return [ self::KEY_TIME => $this->getTime(), self::KEY_LEVEL => $this->getLevel(), self::KEY_PROCESS_ID => $this->getProcessId(), - self::KEY_TYPE_CODE => $this->getTypeCode(), + self::KEY_PROCESS_PATH => $this->getProcessPath(), self::KEY_MESSAGE => $this->getMessage(), ]; } - public function getTime() : string + public function getTime(): string { if ($this->time === null) { throw new \LogicException('Message ' . self::KEY_TIME . ' has not been set.'); @@ -38,7 +38,7 @@ public function getTime() : string return $this->time; } - public function setTime(string $time) : MessageInterface + public function setTime(string $time): MessageInterface { if ($this->time !== null) { throw new \LogicException('Message ' . self::KEY_TIME . ' already set.'); @@ -49,7 +49,7 @@ public function setTime(string $time) : MessageInterface return $this; } - public function getLevel() : string + public function getLevel(): string { if ($this->level === null) { throw new \LogicException('Message ' . self::KEY_LEVEL . ' has not been set.'); @@ -58,7 +58,7 @@ public function getLevel() : string return $this->level; } - public function setLevel(string $level) : MessageInterface + public function setLevel(string $level): MessageInterface { if ($this->level !== null) { throw new \LogicException('Message ' . self::KEY_LEVEL . ' already set.'); @@ -69,7 +69,7 @@ public function setLevel(string $level) : MessageInterface return $this; } - public function getProcessId() : string + public function getProcessId(): string { if ($this->process_id === null) { throw new \LogicException('Message ' . self::KEY_PROCESS_ID . ' has not been set.'); @@ -78,7 +78,7 @@ public function getProcessId() : string return $this->process_id; } - public function setProcessId(string $process_id) : MessageInterface + public function setProcessId(string $process_id): MessageInterface { if ($this->process_id !== null) { throw new \LogicException('Message ' . self::KEY_PROCESS_ID . ' already set.'); @@ -89,27 +89,27 @@ public function setProcessId(string $process_id) : MessageInterface return $this; } - public function getTypeCode() : string + public function getProcessPath(): string { - if ($this->type_code === null) { - throw new \LogicException('Message ' . self::KEY_TYPE_CODE . ' has not been set.'); + if ($this->process_path === null) { + throw new \LogicException('Message ' . self::KEY_PROCESS_PATH . ' has not been set.'); } - return $this->type_code; + return $this->process_path; } - public function setTypeCode(string $type_code) : MessageInterface + public function setProcessPath(string $process_path): MessageInterface { - if ($this->type_code !== null) { - throw new \LogicException('Message ' . self::KEY_TYPE_CODE . ' already set.'); + if ($this->process_path !== null) { + throw new \LogicException('Message ' . self::KEY_PROCESS_PATH . ' already set.'); } - $this->type_code = $type_code; + $this->process_path = $process_path; return $this; } - public function getMessage() : string + public function getMessage(): string { if ($this->message === null) { throw new \LogicException('Message ' . self::KEY_MESSAGE . ' has not been set.'); @@ -118,7 +118,7 @@ public function getMessage() : string return $this->message; } - public function setMessage(string $message) : MessageInterface + public function setMessage(string $message): MessageInterface { if ($this->message !== null) { throw new \LogicException('Message ' . self::KEY_MESSAGE . ' already set.'); diff --git a/src/Process/Pool/Logger/MessageInterface.php b/src/Process/Pool/Logger/MessageInterface.php index bf2a8305..4093f1cd 100644 --- a/src/Process/Pool/Logger/MessageInterface.php +++ b/src/Process/Pool/Logger/MessageInterface.php @@ -19,9 +19,9 @@ public function getProcessId() : string; public function setProcessId(string $process_id) : MessageInterface; - public function getTypeCode() : string; + public function getProcessPath() : string; - public function setTypeCode(string $type_code) : MessageInterface; + public function setProcessPath(string $process_path) : MessageInterface; public function getMessage() : string; diff --git a/src/Process/Pool/LoggerInterface.php b/src/Process/Pool/LoggerInterface.php index 76157bcc..6b768ec3 100644 --- a/src/Process/Pool/LoggerInterface.php +++ b/src/Process/Pool/LoggerInterface.php @@ -16,4 +16,6 @@ public function setIsEnabled(bool $isEnabled): LoggerInterface; public function getLogFormatter() : FormatterInterface; public function setLogFormatter(FormatterInterface $log_formatter) : LoggerInterface; + + public function setLevelFilterMask(array $level_filter_mask): LoggerInterface; } diff --git a/src/Process/Pool/Server.php b/src/Process/Pool/Server.php index f5be99e2..de7fbdcf 100644 --- a/src/Process/Pool/Server.php +++ b/src/Process/Pool/Server.php @@ -21,7 +21,7 @@ class Server extends ProcessAbstract implements ServerInterface public function start(): ProcessInterface { $this->_initialize(); - $this->_getLogger()->info('Starting process pool server...'); + $this->_getLogger()->debug('Starting process pool server...'); if ($this->_getSemaphore()->testAndSetLock($this->_getServerSemaphoreResource())) { $this->_getLogger()->info('Process pool server started.'); $this->_getProcessPool()->start(); @@ -29,7 +29,8 @@ public function start(): ProcessInterface $this->_getProcessSignal()->waitForSignal(); } }else { - $this->_getLogger()->info('Cannot obtain the process pool server mutex. Quitting.'); + $this->_getLogger()->debug('Cannot obtain the process pool server mutex. Quitting.'); + $this->exit(); } return $this; From 08205fbd0babc854b5eeb0ce16c5a6601222c0a0 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Mon, 2 Jul 2018 14:30:53 -0500 Subject: [PATCH 26/30] https://github.com/neighborhoods/Mover/pull/340#event-1712010786 --- src/Process/Pool/Logger.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 3185e5d2..4b6fb9bd 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -41,9 +41,9 @@ public function log($level, $message, array $context = []) $processId = '?'; } - $referenceTime = $this->_getTime()->getUnixReferenceTimeNow(); + $referenceTime = $this->_getTime()->getNow(); $logMessage = $this->getProcessPoolLoggerMessageFactory()->create(); - $logMessage->setTime($referenceTime); + $logMessage->setTime($referenceTime->format('D, d M y H:i:s.u T')); $logMessage->setLevel($level); $logMessage->setProcessId($processId); $logMessage->setProcessPath($this->_getProcess()->getPath()); From a2654f4fe645f20eb250e574748a8fe0598ae54f Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Mon, 2 Jul 2018 15:12:28 -0500 Subject: [PATCH 27/30] Update logger datetime format --- src/Process/Pool/Logger.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Process/Pool/Logger.php b/src/Process/Pool/Logger.php index 4b6fb9bd..a54cb6d6 100644 --- a/src/Process/Pool/Logger.php +++ b/src/Process/Pool/Logger.php @@ -14,7 +14,8 @@ class Logger extends Log\AbstractLogger implements LoggerInterface use Time\AwareTrait; use Logger\Message\Factory\AwareTrait; use Defensive\AwareTrait; - const PROP_IS_ENABLED = 'is_enabled'; + public const PROP_IS_ENABLED = 'is_enabled'; + protected const LOG_DATE_TIME_FORMAT = 'D, d M y H:i:s.u T'; protected $log_formatter; protected $level_filter_mask; @@ -43,7 +44,7 @@ public function log($level, $message, array $context = []) $referenceTime = $this->_getTime()->getNow(); $logMessage = $this->getProcessPoolLoggerMessageFactory()->create(); - $logMessage->setTime($referenceTime->format('D, d M y H:i:s.u T')); + $logMessage->setTime($referenceTime->format(self::LOG_DATE_TIME_FORMAT)); $logMessage->setLevel($level); $logMessage->setProcessId($processId); $logMessage->setProcessPath($this->_getProcess()->getPath()); From 9f4434629286a8495524fd49de7039d3a1edb460 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Tue, 10 Jul 2018 10:57:21 -0500 Subject: [PATCH 28/30] OPS-981 | Shutdown the server when receiving SIGUSR1 from logrotate --- src/ProcessAbstract.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ProcessAbstract.php b/src/ProcessAbstract.php index ea594f9d..fa139390 100644 --- a/src/ProcessAbstract.php +++ b/src/ProcessAbstract.php @@ -56,6 +56,7 @@ protected function _registerSignalHandlers(): ProcessInterface $this->_getProcessSignal()->addSignalHandler(SIGHUP, $this); $this->_getProcessSignal()->addSignalHandler(SIGQUIT, $this); $this->_getProcessSignal()->addSignalHandler(SIGABRT, $this); + $this->_getProcessSignal()->addSignalHandler(SIGUSR1, $this); return $this; } @@ -272,4 +273,4 @@ protected function _getUuidMaximumInteger(): int { return $this->_read(self::PROP_UUID_MAXIMUM_INTEGER); } -} \ No newline at end of file +} From 6be9419414a7c802dde2eebc3ab0e510193135f0 Mon Sep 17 00:00:00 2001 From: Alex Berryman Date: Wed, 25 Jul 2018 16:59:32 -0500 Subject: [PATCH 29/30] example- | log custom event and send to new relic --- example/src/V1/Worker.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/example/src/V1/Worker.php b/example/src/V1/Worker.php index 2288a678..ec048065 100644 --- a/example/src/V1/Worker.php +++ b/example/src/V1/Worker.php @@ -14,9 +14,11 @@ class Worker implements WorkerInterface public function work(): WorkerInterface { + $this->fireEvent('new_worker'); if ($this->getApiV1WorkerService()->getTimesCrashed() === 0) { // Wait for one message to become available. if($this->getV1WorkerQueue()->hasNextMessage()){ + $this->fireEvent('message_received'); // Schedule another kōjō job of the same type. $this->_scheduleNextJob(); @@ -31,6 +33,7 @@ public function work(): WorkerInterface } // Tell Kōjō that we are done and all is well. + $this->fireEvent('complete_success'); $this->getApiV1WorkerService()->requestCompleteSuccess()->applyRequest(); // Fluent interfaces for the love of Pete. @@ -41,6 +44,14 @@ protected function _delegateWork(): WorkerInterface { $workerDelegate = $this->getV1WorkerDelegateRepository()->getV1NewWorkerDelegate(); $workerDelegate->setV1WorkerQueueMessage($this->getV1WorkerQueue()->getNextMessage()); + + $this->fireEvent('working'); + if (extension_loaded('newrelic')) { + newrelic_end_transaction(); + newrelic_start_transaction(ini_get("newrelic.appname")); // start recording a new transaction + newrelic_name_transaction(self::JOB_TYPE_CODE); + } + $workerDelegate->businessLogic(); return $this; @@ -48,6 +59,7 @@ protected function _delegateWork(): WorkerInterface protected function _scheduleNextJob(): WorkerInterface { + $this->fireEvent('schedule_next_job'); $newJobScheduler = $this->getApiV1WorkerService()->getNewJobScheduler(); $newJobScheduler->setJobTypeCode(self::JOB_TYPE_CODE) ->setWorkAtDateTime(new \DateTime('now')) @@ -55,4 +67,14 @@ protected function _scheduleNextJob(): WorkerInterface return $this; } -} \ No newline at end of file + + protected function fireEvent(string $event) : WorkerInterface + { + if (extension_loaded('newrelic')) { + newrelic_record_custom_event($event, ['job_type' => self::JOB_TYPE_CODE]); + } + $this->getApiV1WorkerService()->getLogger()->info($event, ['job_type' => self::JOB_TYPE_CODE]); + + return $this; + } +} From d87adff2030fa0aa167a29875df35ff271bffe3f Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 26 Jul 2018 10:16:03 -0500 Subject: [PATCH 30/30] Include pylon and scaffolding --- .gitignore | 4 +- README.md | 4 +- composer.json | 16 +- composer.lock | 687 ++++-------------- example/composer.json | 11 +- .../Data/Property/Defensive/AwareTrait.php | 52 ++ .../Data/Property/Persistent/AwareTrait.php | 127 ++++ .../ContainerBuilder/Facade.php | 68 ++ .../ContainerBuilder/Facade/AwareTrait.php | 39 + .../ContainerBuilder/FacadeInterface.php | 14 + pylon/src/Symfony/Component/FinderArray.php | 52 ++ .../Component/FinderArrayInterface.php | 22 + pylon/src/Time.php | 46 ++ pylon/src/Time/AwareTrait.php | 31 + pylon/src/TimeInterface.php | 21 + scaffolding/bin/scaffolding.php | 27 + scaffolding/src/AbstractTest.php | 27 + scaffolding/src/Bootstrap.php | 77 ++ scaffolding/src/BootstrapInterface.php | 8 + scaffolding/src/Fixture/AbstractTest.php | 155 ++++ .../src/Fixture/Expression/NumberPool.php | 54 ++ .../Fixture/Expression/Value/AwareTrait.php | 33 + .../DbUnit/DataSet/SymfonyYamlParser.php | 31 + .../TestCase/ContainerBuilder/AwareTrait.php | 38 + scaffolding/src/TestCase/Service.php | 13 + scaffolding/src/TestCase/Service.yml | 7 + .../src/TestCase/Service/AwareTrait.php | 31 + scaffolding/src/TestCase/ServiceInterface.php | 8 + scaffolding/src/root.yml | 10 + .../ForemanInterfaceTest.php | 6 +- 30 files changed, 1167 insertions(+), 552 deletions(-) create mode 100644 pylon/src/Data/Property/Defensive/AwareTrait.php create mode 100644 pylon/src/Data/Property/Persistent/AwareTrait.php create mode 100644 pylon/src/DependencyInjection/ContainerBuilder/Facade.php create mode 100644 pylon/src/DependencyInjection/ContainerBuilder/Facade/AwareTrait.php create mode 100644 pylon/src/DependencyInjection/ContainerBuilder/FacadeInterface.php create mode 100644 pylon/src/Symfony/Component/FinderArray.php create mode 100644 pylon/src/Symfony/Component/FinderArrayInterface.php create mode 100644 pylon/src/Time.php create mode 100644 pylon/src/Time/AwareTrait.php create mode 100644 pylon/src/TimeInterface.php create mode 100755 scaffolding/bin/scaffolding.php create mode 100644 scaffolding/src/AbstractTest.php create mode 100644 scaffolding/src/Bootstrap.php create mode 100644 scaffolding/src/BootstrapInterface.php create mode 100644 scaffolding/src/Fixture/AbstractTest.php create mode 100644 scaffolding/src/Fixture/Expression/NumberPool.php create mode 100644 scaffolding/src/Fixture/Expression/Value/AwareTrait.php create mode 100644 scaffolding/src/PHPUnit/DbUnit/DataSet/SymfonyYamlParser.php create mode 100644 scaffolding/src/TestCase/ContainerBuilder/AwareTrait.php create mode 100644 scaffolding/src/TestCase/Service.php create mode 100644 scaffolding/src/TestCase/Service.yml create mode 100644 scaffolding/src/TestCase/Service/AwareTrait.php create mode 100644 scaffolding/src/TestCase/ServiceInterface.php create mode 100644 scaffolding/src/root.yml diff --git a/.gitignore b/.gitignore index 0a90e5ae..65cef096 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ vendor/ +!example/vendor/neighborhoods/kojo .composer/ -phpunit.xml \ No newline at end of file +phpunit.xml +.idea/ \ No newline at end of file diff --git a/README.md b/README.md index ba5a7688..ef378715 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,6 @@ A distributed task manager. ### Example usage ```bash $ bin/kojo process:pool:server:start $PWD/example -``` \ No newline at end of file +``` + +### Setting up a Worker. \ No newline at end of file diff --git a/composer.json b/composer.json index e0f068ae..b1409d43 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "neighborhoods/kojo", "type": "library", "description": "Neighborhoods Kōjō is a distributed task manager.", - "license": "proprietary", + "license": "MIT", "keywords": [], "authors": [ { @@ -10,6 +10,9 @@ "email": "brad.wilson@neighborhoods.com" } ], + "config": { + "sort-packages": true + }, "repositories": [ { "type": "composer", @@ -28,20 +31,21 @@ "symfony/finder": "^4.0", "zendframework/zend-db": "^2.8", "dragonmantank/cron-expression": "^2.0", - "neighborhoods/pylon": "^1.0", "doctrine/dbal": "^2.7" }, "require-dev": { "phpunit/phpunit": "^7.0", - "phpunit/dbunit": "^4.0", - "neighborhoods/scaffolding": "^1.0" + "phpunit/dbunit": "^4.0" }, "bin": [ - "bin/kojo" + "bin/kojo", + "scaffolding/bin/scaffolding.php" ], "autoload": { "psr-4": { - "Neighborhoods\\Kojo\\": "src" + "Neighborhoods\\Kojo\\": "src", + "Neighborhoods\\Scaffolding\\": "scaffolding/src", + "Neighborhoods\\Pylon\\": "pylon/src" } }, "autoload-dev": { diff --git a/composer.lock b/composer.lock index 22506f5d..142b6975 100644 --- a/composer.lock +++ b/composer.lock @@ -4,76 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "3382a0a8f83c6ac1ba27f686535d85bd", + "content-hash": "86aebed19a3392bb2962386ac7369c61", "packages": [ - { - "name": "doctrine/annotations", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", - "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "php": "^7.1" - }, - "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2017-12-06T07:11:42+00:00" - }, { "name": "doctrine/cache", "version": "v1.7.1", @@ -148,170 +80,33 @@ ], "time": "2017-08-25T07:02:50+00:00" }, - { - "name": "doctrine/collections", - "version": "v1.5.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/collections.git", - "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/a01ee38fcd999f34d9bfbcee59dbda5105449cbf", - "reference": "a01ee38fcd999f34d9bfbcee59dbda5105449cbf", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "doctrine/coding-standard": "~0.1@dev", - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Collections\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Collections Abstraction library", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "array", - "collections", - "iterator" - ], - "time": "2017-07-22T10:37:32+00:00" - }, - { - "name": "doctrine/common", - "version": "v2.8.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "f68c297ce6455e8fd794aa8ffaf9fa458f6ade66" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/f68c297ce6455e8fd794aa8ffaf9fa458f6ade66", - "reference": "f68c297ce6455e8fd794aa8ffaf9fa458f6ade66", - "shasum": "" - }, - "require": { - "doctrine/annotations": "1.*", - "doctrine/cache": "1.*", - "doctrine/collections": "1.*", - "doctrine/inflector": "1.*", - "doctrine/lexer": "1.*", - "php": "~7.1" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Common Library for Doctrine projects", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "collections", - "eventmanager", - "persistence", - "spl" - ], - "time": "2017-08-31T08:43:38+00:00" - }, { "name": "doctrine/dbal", - "version": "v2.7.1", + "version": "v2.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "11037b4352c008373561dc6fc836834eed80c3b5" + "reference": "5140a64c08b4b607b9bedaae0cedd26f04a0e621" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/11037b4352c008373561dc6fc836834eed80c3b5", - "reference": "11037b4352c008373561dc6fc836834eed80c3b5", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/5140a64c08b4b607b9bedaae0cedd26f04a0e621", + "reference": "5140a64c08b4b607b9bedaae0cedd26f04a0e621", "shasum": "" }, "require": { - "doctrine/common": "^2.7.1", + "doctrine/cache": "^1.0", + "doctrine/event-manager": "^1.0", "ext-pdo": "*", "php": "^7.1" }, "require-dev": { "doctrine/coding-standard": "^4.0", - "phpunit/phpunit": "^7.0", + "jetbrains/phpstorm-stubs": "^2018.1.2", + "phpstan/phpstan": "^0.10.1", + "phpunit/phpunit": "^7.1.2", "phpunit/phpunit-mock-objects": "!=3.2.4,!=3.2.5", - "symfony/console": "^2.0.5||^3.0", + "symfony/console": "^2.0.5|^3.0|^4.0", "symfony/phpunit-bridge": "^3.4.5|^4.0.5" }, "suggest": { @@ -323,7 +118,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7.x-dev" + "dev-master": "2.8.x-dev", + "dev-develop": "3.0.x-dev" } }, "autoload": { @@ -361,37 +157,41 @@ "persistence", "queryobject" ], - "time": "2018-04-07T18:44:18+00:00" + "time": "2018-07-13T03:16:35+00:00" }, { - "name": "doctrine/inflector", - "version": "v1.3.0", + "name": "doctrine/event-manager", + "version": "v1.0.0", "source": { "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "5527a48b7313d15261292c149e55e26eae771b0a" + "url": "https://github.com/doctrine/event-manager.git", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a", - "reference": "5527a48b7313d15261292c149e55e26eae771b0a", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", "shasum": "" }, "require": { "php": "^7.1" }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, "require-dev": { - "phpunit/phpunit": "^6.2" + "doctrine/coding-standard": "^4.0", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { - "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" + "Doctrine\\Common\\": "lib/Doctrine/Common" } }, "notification-url": "https://packagist.org/downloads/", @@ -418,84 +218,33 @@ { "name": "Johannes Schmitt", "email": "schmittjoh@gmail.com" - } - ], - "description": "Common String Manipulations with regard to casing and singular/plural rules.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "inflection", - "pluralize", - "singularize", - "string" - ], - "time": "2018-01-09T20:05:19+00:00" - }, - { - "name": "doctrine/lexer", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" }, { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" } ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", + "description": "Doctrine Event Manager component", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", "keywords": [ - "lexer", - "parser" + "event", + "eventdispatcher", + "eventmanager" ], - "time": "2014-09-09T13:34:57+00:00" + "time": "2018-06-11T11:59:03+00:00" }, { "name": "dragonmantank/cron-expression", - "version": "v2.1.0", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "3f00985deec8df53d4cc1e5c33619bda1ee309a5" + "reference": "92a2c3768d50e21a1f26a53cb795ce72806266c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/3f00985deec8df53d4cc1e5c33619bda1ee309a5", - "reference": "3f00985deec8df53d4cc1e5c33619bda1ee309a5", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/92a2c3768d50e21a1f26a53cb795ce72806266c5", + "reference": "92a2c3768d50e21a1f26a53cb795ce72806266c5", "shasum": "" }, "require": { @@ -531,45 +280,7 @@ "cron", "schedule" ], - "time": "2018-04-06T15:51:55+00:00" - }, - { - "name": "neighborhoods/pylon", - "version": "1.0.0", - "source": { - "type": "git", - "url": "git@github.com:neighborhoods/pylon.git", - "reference": "395e9d30b4ef5ba3e117851be97587464fc101e3" - }, - "dist": { - "type": "tar", - "url": "https://satis.neighborhoods.com/dist/neighborhoods/pylon/neighborhoods-pylon-395e9d30b4ef5ba3e117851be97587464fc101e3-zip-d14393.tar", - "reference": "395e9d30b4ef5ba3e117851be97587464fc101e3", - "shasum": "c917dd0a4b6cedf90ea4e16c5e0aae8c75814c53" - }, - "require": { - "php": ">=7.1", - "symfony/config": "^4.0", - "symfony/dependency-injection": "^4.0", - "symfony/finder": "^4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Neighborhoods\\Pylon\\": "src" - } - }, - "license": [ - "proprietary" - ], - "authors": [ - { - "name": "Brad Wilson", - "email": "brad.wilson@neighborhoods.com" - } - ], - "description": "Neighborhoods Pylon is a collection of useful, but most importantly, generic objects.", - "time": "2018-04-18T19:29:35+00:00" + "time": "2018-06-06T03:12:17+00:00" }, { "name": "psr/cache", @@ -763,16 +474,16 @@ }, { "name": "symfony/cache", - "version": "v4.0.11", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "bd6d0a969c80b00630e9e2f0ab14ad4518712ec8" + "reference": "42191caaf21ab7be0eb623d6c572e0b2932a8880" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/bd6d0a969c80b00630e9e2f0ab14ad4518712ec8", - "reference": "bd6d0a969c80b00630e9e2f0ab14ad4518712ec8", + "url": "https://api.github.com/repos/symfony/cache/zipball/42191caaf21ab7be0eb623d6c572e0b2932a8880", + "reference": "42191caaf21ab7be0eb623d6c572e0b2932a8880", "shasum": "" }, "require": { @@ -797,7 +508,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -828,20 +539,20 @@ "caching", "psr6" ], - "time": "2018-05-16T09:05:32+00:00" + "time": "2018-07-03T17:58:50+00:00" }, { "name": "symfony/config", - "version": "v4.0.11", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "aaef656e99c5396d6118970abd1ceb11fa74551d" + "reference": "e57e7b573df9d0eaa8c0152768c708ee7ea2b8e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/aaef656e99c5396d6118970abd1ceb11fa74551d", - "reference": "aaef656e99c5396d6118970abd1ceb11fa74551d", + "url": "https://api.github.com/repos/symfony/config/zipball/e57e7b573df9d0eaa8c0152768c708ee7ea2b8e5", + "reference": "e57e7b573df9d0eaa8c0152768c708ee7ea2b8e5", "shasum": "" }, "require": { @@ -864,7 +575,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -891,20 +602,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-05-16T09:05:32+00:00" + "time": "2018-06-20T11:15:17+00:00" }, { "name": "symfony/console", - "version": "v4.0.11", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "058f120b8e06ebcd7b211de5ffae07b2db00fbdd" + "reference": "5c31f6a97c1c240707f6d786e7e59bfacdbc0219" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/058f120b8e06ebcd7b211de5ffae07b2db00fbdd", - "reference": "058f120b8e06ebcd7b211de5ffae07b2db00fbdd", + "url": "https://api.github.com/repos/symfony/console/zipball/5c31f6a97c1c240707f6d786e7e59bfacdbc0219", + "reference": "5c31f6a97c1c240707f6d786e7e59bfacdbc0219", "shasum": "" }, "require": { @@ -932,7 +643,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -959,20 +670,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-05-16T09:05:32+00:00" + "time": "2018-07-16T14:05:40+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.0.11", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "4b272d65e9c0d2d40e2d23bab3c7a184ad4a3a18" + "reference": "62912ab79facdbdaa0849f6c2fe4734b7b60f5cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4b272d65e9c0d2d40e2d23bab3c7a184ad4a3a18", - "reference": "4b272d65e9c0d2d40e2d23bab3c7a184ad4a3a18", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/62912ab79facdbdaa0849f6c2fe4734b7b60f5cc", + "reference": "62912ab79facdbdaa0849f6c2fe4734b7b60f5cc", "shasum": "" }, "require": { @@ -980,7 +691,7 @@ "psr/container": "^1.0" }, "conflict": { - "symfony/config": "<3.4", + "symfony/config": "<4.1.1", "symfony/finder": "<3.4", "symfony/proxy-manager-bridge": "<3.4", "symfony/yaml": "<3.4" @@ -989,7 +700,7 @@ "psr/container-implementation": "1.0" }, "require-dev": { - "symfony/config": "~3.4|~4.0", + "symfony/config": "~4.1", "symfony/expression-language": "~3.4|~4.0", "symfony/yaml": "~3.4|~4.0" }, @@ -1003,7 +714,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -1030,20 +741,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-05-25T11:57:52+00:00" + "time": "2018-07-16T14:05:40+00:00" }, { "name": "symfony/expression-language", - "version": "v4.0.11", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "b826c255f22333eccd3365734d2c4e150c284843" + "reference": "81653bbb8e0feff271bebfdea492386f1c75c098" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/b826c255f22333eccd3365734d2c4e150c284843", - "reference": "b826c255f22333eccd3365734d2c4e150c284843", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/81653bbb8e0feff271bebfdea492386f1c75c098", + "reference": "81653bbb8e0feff271bebfdea492386f1c75c098", "shasum": "" }, "require": { @@ -1053,7 +764,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -1080,20 +791,20 @@ ], "description": "Symfony ExpressionLanguage Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:38:00+00:00" + "time": "2018-06-21T11:15:46+00:00" }, { "name": "symfony/filesystem", - "version": "v4.0.11", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04" + "reference": "562bf7005b55fd80d26b582d28e3e10f2dd5ae9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04", - "reference": "7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/562bf7005b55fd80d26b582d28e3e10f2dd5ae9c", + "reference": "562bf7005b55fd80d26b582d28e3e10f2dd5ae9c", "shasum": "" }, "require": { @@ -1103,7 +814,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -1130,20 +841,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-05-16T09:05:32+00:00" + "time": "2018-05-30T07:26:09+00:00" }, { "name": "symfony/finder", - "version": "v4.0.11", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8c633f5a815903a1fe6e3fc135f207267a8a79af" + "reference": "84714b8417d19e4ba02ea78a41a975b3efaafddb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8c633f5a815903a1fe6e3fc135f207267a8a79af", - "reference": "8c633f5a815903a1fe6e3fc135f207267a8a79af", + "url": "https://api.github.com/repos/symfony/finder/zipball/84714b8417d19e4ba02ea78a41a975b3efaafddb", + "reference": "84714b8417d19e4ba02ea78a41a975b3efaafddb", "shasum": "" }, "require": { @@ -1152,7 +863,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -1179,7 +890,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-05-16T09:05:32+00:00" + "time": "2018-06-19T21:38:16+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1297,16 +1008,16 @@ }, { "name": "symfony/yaml", - "version": "v4.0.11", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "048b1be5fb96e73ff1d065f5e7e23f84415ac907" + "reference": "80e4bfa9685fc4a09acc4a857ec16974a9cd944e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/048b1be5fb96e73ff1d065f5e7e23f84415ac907", - "reference": "048b1be5fb96e73ff1d065f5e7e23f84415ac907", + "url": "https://api.github.com/repos/symfony/yaml/zipball/80e4bfa9685fc4a09acc4a857ec16974a9cd944e", + "reference": "80e4bfa9685fc4a09acc4a857ec16974a9cd944e", "shasum": "" }, "require": { @@ -1325,7 +1036,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -1352,7 +1063,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-05-07T07:12:24+00:00" + "time": "2018-05-30T07:26:09+00:00" }, { "name": "zendframework/zend-db", @@ -1516,25 +1227,28 @@ }, { "name": "myclabs/deep-copy", - "version": "1.7.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", - "phpunit/phpunit": "^4.1" + "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { @@ -1557,73 +1271,26 @@ "object", "object graph" ], - "time": "2017-10-19T19:58:43+00:00" - }, - { - "name": "neighborhoods/scaffolding", - "version": "1.1.0", - "source": { - "type": "git", - "url": "git@github.com:neighborhoods/Scaffolding.git", - "reference": "b054606cbc696cbe369b9b0de217076da3fba6e5" - }, - "dist": { - "type": "tar", - "url": "https://satis.neighborhoods.com/dist/neighborhoods/scaffolding/neighborhoods-scaffolding-b054606cbc696cbe369b9b0de217076da3fba6e5-zip-990c14.tar", - "reference": "b054606cbc696cbe369b9b0de217076da3fba6e5", - "shasum": "71f21e3c52bf74c7acf2d222962ae14fcf876ade" - }, - "require": { - "neighborhoods/pylon": "^1.0.0", - "php": ">=7.1", - "phpunit/dbunit": "^4.0", - "phpunit/phpunit": "^7.0", - "symfony/config": "^4.0", - "symfony/dependency-injection": "^4.0", - "symfony/expression-language": "^4.0", - "symfony/filesystem": "^4.0", - "symfony/finder": "^4.0", - "symfony/yaml": "^4.0" - }, - "bin": [ - "bin/scaffolding.php" - ], - "type": "library", - "autoload": { - "psr-4": { - "Neighborhoods\\Scaffolding\\": "src" - } - }, - "license": [ - "proprietary" - ], - "authors": [ - { - "name": "Neighborhoods.com", - "email": "brad.wilson@neighborhoods.com" - } - ], - "description": "Neighborhoods Scaffolding is meant to make the creation of contract testing easy and fast.", - "time": "2018-05-22T21:18:48+00:00" + "time": "2018-06-11T23:09:50+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.1", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^1.0.1", + "phar-io/version": "^2.0", "php": "^5.6 || ^7.0" }, "type": "library", @@ -1659,20 +1326,20 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "time": "2018-07-08T19:23:20+00:00" }, { "name": "phar-io/version", - "version": "1.0.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", "shasum": "" }, "require": { @@ -1706,7 +1373,7 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "time": "2018-07-08T19:19:57+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1977,23 +1644,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "6.0.5", + "version": "6.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "4cab20a326d14de7575a8e235c70d879b569a57a" + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4cab20a326d14de7575a8e235c70d879b569a57a", - "reference": "4cab20a326d14de7575a8e235c70d879b569a57a", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a", + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", "php": "^7.1", - "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-file-iterator": "^2.0", "phpunit/php-text-template": "^1.2.1", "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", @@ -2036,29 +1703,29 @@ "testing", "xunit" ], - "time": "2018-05-28T11:49:20+00:00" + "time": "2018-06-01T07:51:50+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c", + "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -2073,7 +1740,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -2083,7 +1750,7 @@ "filesystem", "iterator" ], - "time": "2017-11-27T13:52:08+00:00" + "time": "2018-06-11T11:44:00+00:00" }, { "name": "phpunit/php-text-template", @@ -2226,34 +1893,34 @@ }, { "name": "phpunit/phpunit", - "version": "7.1.5", + "version": "7.2.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ca64dba53b88aba6af32aebc6b388068db95c435" + "reference": "8e878aff7917ef66e702e03d1359b16eee254e2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ca64dba53b88aba6af32aebc6b388068db95c435", - "reference": "ca64dba53b88aba6af32aebc6b388068db95c435", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8e878aff7917ef66e702e03d1359b16eee254e2c", + "reference": "8e878aff7917ef66e702e03d1359b16eee254e2c", "shasum": "" }, "require": { + "doctrine/instantiator": "^1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.2", + "phar-io/version": "^2.0", "php": "^7.1", "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.1", - "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.0", - "phpunit/phpunit-mock-objects": "^6.1.1", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", "sebastian/environment": "^3.1", @@ -2263,10 +1930,14 @@ "sebastian/resource-operations": "^1.0", "sebastian/version": "^2.0.1" }, + "conflict": { + "phpunit/phpunit-mock-objects": "*" + }, "require-dev": { "ext-pdo": "*" }, "suggest": { + "ext-soap": "*", "ext-xdebug": "*", "phpunit/php-invoker": "^2.0" }, @@ -2276,7 +1947,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.1-dev" + "dev-master": "7.2-dev" } }, "autoload": { @@ -2302,63 +1973,7 @@ "testing", "xunit" ], - "time": "2018-04-29T15:09:19+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "6.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "f9756fd4f43f014cb2dca98deeaaa8ce5500a36e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/f9756fd4f43f014cb2dca98deeaaa8ce5500a36e", - "reference": "f9756fd4f43f014cb2dca98deeaaa8ce5500a36e", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.1", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2018-05-29T13:54:20+00:00" + "time": "2018-07-15T05:20:50+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -2407,16 +2022,16 @@ }, { "name": "sebastian/comparator", - "version": "3.0.0", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5" + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ed5fd2281113729f1ebcc64d101ad66028aeb3d5", - "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", "shasum": "" }, "require": { @@ -2467,20 +2082,20 @@ "compare", "equality" ], - "time": "2018-04-18T13:33:00+00:00" + "time": "2018-07-12T15:12:46+00:00" }, { "name": "sebastian/diff", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8" + "reference": "366541b989927187c4ca70490a35615d3fef2dce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8", - "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", + "reference": "366541b989927187c4ca70490a35615d3fef2dce", "shasum": "" }, "require": { @@ -2523,7 +2138,7 @@ "unidiff", "unified diff" ], - "time": "2018-02-01T13:45:15+00:00" + "time": "2018-06-10T07:54:39+00:00" }, { "name": "sebastian/environment", diff --git a/example/composer.json b/example/composer.json index 4194cd66..0f946582 100644 --- a/example/composer.json +++ b/example/composer.json @@ -2,7 +2,7 @@ "name": "neighborhoods/kojo_example", "type": "library", "description": "Neighborhoods Kōjō Example provides an example of using kōjō and protean.", - "license": "proprietary", + "license": "MIT", "keywords": [], "authors": [ { @@ -10,6 +10,9 @@ "email": "brad.wilson@neighborhoods.com" } ], + "config": { + "sort-packages": true + }, "repositories": [ { "type": "composer", @@ -18,13 +21,11 @@ ], "require": { "php": ">=7.1", - "neighborhoods/kojo": "^2.0.0", - "neighborhoods/pylon": "^1.0.0", + "neighborhoods/kojo": "^3.0.0", "aws/aws-sdk-php": "2.*" }, "require-dev": { - "php": ">=7.1", - "neighborhoods/scaffolding": "^1.0.0" + "php": ">=7.1" }, "autoload": { "psr-4": { diff --git a/pylon/src/Data/Property/Defensive/AwareTrait.php b/pylon/src/Data/Property/Defensive/AwareTrait.php new file mode 100644 index 00000000..fa9bd37d --- /dev/null +++ b/pylon/src/Data/Property/Defensive/AwareTrait.php @@ -0,0 +1,52 @@ +_exists($propertyName), new \LogicException($propertyName . ' is already created.')); + $this->_defendedProperties[$propertyName] = $propertyValue; + + return $this; + } + + protected function &_read(string $propertyName) + { + assert($this->_exists($propertyName), new \LogicException($propertyName . ' is not created.')); + + return $this->_defendedProperties[$propertyName]; + } + + protected function _update(string $propertyName, $propertyValue) + { + assert($this->_exists($propertyName), new \LogicException($propertyName . ' is not created.')); + $this->_defendedProperties[$propertyName] = $propertyValue; + + return $this; + } + + protected function _createOrUpdate(string $propertyName, $propertyValue) + { + $this->_defendedProperties[$propertyName] = $propertyValue; + + return $this; + } + + protected function _delete(string $propertyName) + { + assert($this->_exists($propertyName), new \LogicException($propertyName . ' is not created.')); + unset($this->_defendedProperties[$propertyName]); + + return $this; + } + + protected function _exists(string $propertyName): bool + { + return isset($this->_defendedProperties[$propertyName]) ? true : false; + } +} \ No newline at end of file diff --git a/pylon/src/Data/Property/Persistent/AwareTrait.php b/pylon/src/Data/Property/Persistent/AwareTrait.php new file mode 100644 index 00000000..35f3ab2d --- /dev/null +++ b/pylon/src/Data/Property/Persistent/AwareTrait.php @@ -0,0 +1,127 @@ +_hasPersistentProperties()) { + $this->_persistentProperties = $persistentProperties; + $this->_changedPersistentProperties = $persistentProperties; + }else { + throw new \LogicException('Persistent properties is already set.'); + } + + return $this; + } + + protected function _emptyPersistentProperties() + { + if ($this->_hasPersistentProperties()) { + $this->_persistentProperties = []; + $this->_changedPersistentProperties = []; + }else { + throw new \LogicException('Persistent properties is not set.'); + } + + return $this; + } + + protected function _hydrate(array $persistentProperties) + { + $this->_persistentProperties = array_replace($this->_persistentProperties, $persistentProperties); + $this->_changedPersistentProperties = []; + + return $this; + } + + protected function _createPersistentProperty(string $persistentPropertyName, $persistentPropertyValue) + { + if ($this->_hasPersistentProperty($persistentPropertyName)) { + throw new \LogicException('Persistent property ' . $persistentPropertyName . ' is already set.'); + }else { + $this->_persistentProperties[$persistentPropertyName] = $persistentPropertyValue; + $this->_changedPersistentProperties[$persistentPropertyName] = $persistentPropertyValue; + } + + return $this; + } + + protected function _readPersistentProperty(string $persistentPropertyName) + { + if (!isset($this->_persistentProperties[$persistentPropertyName])) { + throw new \LogicException('Persistent property ' . $persistentPropertyName . ' is not set'); + } + + return $this->_persistentProperties[$persistentPropertyName]; + } + + protected function _unsetPersistentProperty(string $persistentPropertyName) + { + if ($this->_hasPersistentProperty($persistentPropertyName)) { + unset($this->_persistentProperties[$persistentPropertyName]); + $this->_changedPersistentProperties[$persistentPropertyName] = null; + }else { + throw new \LogicException('Persistent property is not set.'); + } + + return $this; + } + + public function readPersistentProperties(): array + { + if (!$this->_hasPersistentProperties()) { + throw new \LogicException('Persistent properties is not set.'); + } + + return $this->_persistentProperties; + } + + protected function _createOrUpdatePersistentProperty(string $persistentPropertyName, $persistentPropertyValue) + { + $this->_persistentProperties[$persistentPropertyName] = $persistentPropertyValue; + $this->_changedPersistentProperties[$persistentPropertyName] = $persistentPropertyValue; + + return $this; + } + + protected function _hasPersistentProperty(string $persistentPropertyName): bool + { + return isset($this->_persistentProperties[$persistentPropertyName]); + } + + protected function _hasPersistentProperties(): bool + { + return empty($this->_persistentProperties) ? false : true; + } + + public function hasChangedPersistentProperties(): bool + { + return empty($this->_changedPersistentProperties) ? false : true; + } + + protected function _readChangedPersistentProperties(): array + { + if (!$this->hasChangedPersistentProperties()) { + throw new \LogicException('Changed persistent properties is not set.'); + } + + return $this->_changedPersistentProperties; + } + + protected function _emptyChangedPersistentProperties() + { + if ($this->hasChangedPersistentProperties()) { + $this->_changedPersistentProperties = []; + }else { + throw new \LogicException('Changed persistent properties is not set.'); + } + + return $this; + } +} \ No newline at end of file diff --git a/pylon/src/DependencyInjection/ContainerBuilder/Facade.php b/pylon/src/DependencyInjection/ContainerBuilder/Facade.php new file mode 100644 index 00000000..6fef6f66 --- /dev/null +++ b/pylon/src/DependencyInjection/ContainerBuilder/Facade.php @@ -0,0 +1,68 @@ +_getFinderArray()->append($finder); + + return $this; + } + + protected function _getFinderArray(): FinderArrayInterface + { + if ($this->_finderArray === null) { + $this->_finderArray = new FinderArray(); + } + + return $this->_finderArray; + } + + protected function _getYamlServicesFilePaths(): array + { + if (empty($this->_yamlServicesFilePaths)) { + foreach ($this->_getFinderArray() as $finder) { + foreach ($finder as $directoryPath => $file) { + $this->_yamlServicesFilePaths[] = $file->getPathname(); + } + } + } + + return $this->_yamlServicesFilePaths; + } + + public function getContainerBuilder(): ContainerBuilder + { + if ($this->_containerBuilder === null) { + $containerBuilder = new ContainerBuilder(); + $loader = new YamlFileLoader($containerBuilder, new FileLocator(__DIR__)); + foreach ($this->_getYamlServicesFilePaths() as $servicesYmlFilePath) { + $loader->import($servicesYmlFilePath); + } + $passes = [new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass()]; + $repeatedPass = new RepeatedPass($passes); + $repeatedPass->process($containerBuilder); + $containerBuilder->compile(true); + $this->_containerBuilder = $containerBuilder; + } + + return $this->_containerBuilder; + } +} \ No newline at end of file diff --git a/pylon/src/DependencyInjection/ContainerBuilder/Facade/AwareTrait.php b/pylon/src/DependencyInjection/ContainerBuilder/Facade/AwareTrait.php new file mode 100644 index 00000000..5f4b966b --- /dev/null +++ b/pylon/src/DependencyInjection/ContainerBuilder/Facade/AwareTrait.php @@ -0,0 +1,39 @@ +_create(FacadeInterface::class, $dependencyInjectionContainerBuilderFacade); + + return $this; + } + + protected function _getDependencyInjectionContainerBuilderFacade(): FacadeInterface + { + return $this->_read(FacadeInterface::class); + } + + protected function _getDependencyInjectionContainerBuilderFacadeClone(): FacadeInterface + { + return clone $this->_getDependencyInjectionContainerBuilderFacade(); + } + + protected function _hasDependencyInjectionContainerBuilderFacade(): bool + { + return $this->_exists(FacadeInterface::class); + } + + protected function _unsetDependencyInjectionContainerBuilderFacade(): self + { + $this->_delete(FacadeInterface::class); + + return $this; + } +} \ No newline at end of file diff --git a/pylon/src/DependencyInjection/ContainerBuilder/FacadeInterface.php b/pylon/src/DependencyInjection/ContainerBuilder/FacadeInterface.php new file mode 100644 index 00000000..ad7e3389 --- /dev/null +++ b/pylon/src/DependencyInjection/ContainerBuilder/FacadeInterface.php @@ -0,0 +1,14 @@ +_assertValidArrayType(...$finders); + } + + parent::__construct($finders, $flags); + } + + public function offsetGet($index): Finder + { + return $this->_assertValidArrayItemType(parent::offsetGet($index)); + } + + /** @param Finder $finder */ + public function offsetSet($index, $finder) + { + parent::offsetSet($index, $this->_assertValidArrayItemType($finder)); + } + + /** @param Finder $finder */ + public function append($finder) + { + $this->_assertValidArrayItemType($finder); + parent::append($finder); + } + + public function current(): Finder + { + return parent::current(); + } + + protected function _assertValidArrayItemType(Finder $finder) + { + return $finder; + } + + protected function _assertValidArrayType(Finder ...$finders): FinderArrayInterface + { + return $this; + } +} \ No newline at end of file diff --git a/pylon/src/Symfony/Component/FinderArrayInterface.php b/pylon/src/Symfony/Component/FinderArrayInterface.php new file mode 100644 index 00000000..c12f1cc7 --- /dev/null +++ b/pylon/src/Symfony/Component/FinderArrayInterface.php @@ -0,0 +1,22 @@ +setTimezone($this->getDateTimeZone($timezoneCode)); + + return $now; + } + + public function getUnixReferenceTimeNow(): string + { + return sprintf('%f', microtime(true)); + } + + public function validateTimestamp(string $timestamp, string $format = TimeInterface::MYSQL_DATE_TIME_FORMAT): bool + { + $dateTime = \DateTime::createFromFormat($format, $timestamp); + + return $dateTime && $dateTime->format($format) == $timestamp; + } + + public function getDateTimeZone(string $timezoneCode = self::DEFAULT_TIMEZONE_CODE): \DateTimeZone + { + if (!isset($this->_dateTimeZones[$timezoneCode])) { + $dateTimeZone = new \DateTimeZone($timezoneCode); + $this->_dateTimeZones[$timezoneCode] = $dateTimeZone; + } + + return clone $this->_dateTimeZones[$timezoneCode]; + } + + public function getNewDateInterval(string $intervalSpec): \DateInterval + { + return new \DateInterval($intervalSpec); + } +} \ No newline at end of file diff --git a/pylon/src/Time/AwareTrait.php b/pylon/src/Time/AwareTrait.php new file mode 100644 index 00000000..9176f8a0 --- /dev/null +++ b/pylon/src/Time/AwareTrait.php @@ -0,0 +1,31 @@ +_time === null) { + $this->_time = $time; + }else { + throw new \Exception('Time is already set.'); + } + + return $this; + } + + protected function _getTime(): TimeInterface + { + if ($this->_time === null) { + throw new \LogicException('Time is not set.'); + } + + return $this->_time; + } +} \ No newline at end of file diff --git a/pylon/src/TimeInterface.php b/pylon/src/TimeInterface.php new file mode 100644 index 00000000..600c8ef4 --- /dev/null +++ b/pylon/src/TimeInterface.php @@ -0,0 +1,21 @@ +getMessage(); + exit(1); +} + +Bootstrap::setUp(); + +return; \ No newline at end of file diff --git a/scaffolding/src/AbstractTest.php b/scaffolding/src/AbstractTest.php new file mode 100644 index 00000000..34751c21 --- /dev/null +++ b/scaffolding/src/AbstractTest.php @@ -0,0 +1,27 @@ +addServicesYmlFilePath($ymlServiceFilePath); + $testCaseService = $this->getContainerBuilder()->get('neighborhoods.scaffolding.testcase.service'); + $this->setTestCaseService($testCaseService); + + parent::setUp(); + } +} \ No newline at end of file diff --git a/scaffolding/src/Bootstrap.php b/scaffolding/src/Bootstrap.php new file mode 100644 index 00000000..cb197f56 --- /dev/null +++ b/scaffolding/src/Bootstrap.php @@ -0,0 +1,77 @@ +addFinder(self::_getApplicationRootDirectoryFinder()); + self::getContainerBuilderFacade()->addFinder(self::_getScaffoldingRootDirectoryFinder()); + self::getContainerBuilderFacade()->addFinder(self::_getTestApplicationRootDirectoryFinder()); + + return; + } + + protected static function _getScaffoldingRootDirectoryFinder(): Finder + { + if (self::$_scaffoldingRootDirectoryFinder === null) { + $scaffoldingRootDirectoryFinder = new Finder(); + $scaffoldingRootDirectoryFinder->files()->in(self::_getScaffoldingRootDirectoryPath()); + $scaffoldingRootDirectoryFinder->name('*.yml'); + self::$_scaffoldingRootDirectoryFinder = $scaffoldingRootDirectoryFinder; + } + + return self::$_scaffoldingRootDirectoryFinder; + } + + protected static function _getApplicationRootDirectoryFinder(): Finder + { + if (self::$_applicationRootDirectoryFinder === null) { + $applicationRootDirectoryFinder = new Finder(); + $applicationRootDirectoryFinder->files()->in(self::_getScaffoldingRootDirectoryPath() . '/../../../../src'); + $applicationRootDirectoryFinder->name('*.yml'); + self::$_applicationRootDirectoryFinder = $applicationRootDirectoryFinder; + } + + return self::$_applicationRootDirectoryFinder; + } + + protected static function _getTestApplicationRootDirectoryFinder(): Finder + { + if (self::$_testApplicationRootDirectoryFinder === null) { + $testApplicationRootDirectoryFinder = new Finder(); + $testApplicationRootDirectoryFinder->files()->in(self::_getScaffoldingRootDirectoryPath() . '/../../../../tests/Application'); + $testApplicationRootDirectoryFinder->name('*.yml'); + self::$_testApplicationRootDirectoryFinder = $testApplicationRootDirectoryFinder; + } + + return self::$_testApplicationRootDirectoryFinder; + } + + protected static function _getScaffoldingRootDirectoryPath(): string + { + $scaffoldingRootDirectoryPath = dirname(__FILE__); + + return $scaffoldingRootDirectoryPath; + } + + public static function getContainerBuilderFacade(): Facade + { + if (self::$_containerBuilderFacade === null) { + self::$_containerBuilderFacade = new Facade(); + } + + return self::$_containerBuilderFacade; + } +} \ No newline at end of file diff --git a/scaffolding/src/BootstrapInterface.php b/scaffolding/src/BootstrapInterface.php new file mode 100644 index 00000000..41ec68c3 --- /dev/null +++ b/scaffolding/src/BootstrapInterface.php @@ -0,0 +1,8 @@ +_getContainerBuilderFacade()->addFinder($this->_getTestCaseRootDirectoryFinder()); + $containerBuilder = $this->_getContainerBuilderFacade()->getContainerBuilder(); + $this->setTestCaseService($containerBuilder->get('neighborhoods.scaffolding.testcase.service')); + $tearDown = $containerBuilder->get('db.tear_down'); + $tearDown->uninstall(); + $setup = $containerBuilder->get('db.setup'); + $setup->install(); + $redis = $containerBuilder->get('redis.factory')->create(); + $redis->flushAll(); + + parent::setUp(); + } + + protected function getSetUpOperation() + { + return Factory::CLEAN_INSERT(true); + } + + protected function _getTestCaseRootDirectoryFinder(): Finder + { + if ($this->_testRootDirectoryFinder === null) { + $testRootDirectoryFinder = new Finder(); + $testRootDirectoryFinder->files()->in($this->_getTestCaseRootDirectoryPath()); + $testRootDirectoryFinder->exclude(['fixtures']); + $testRootDirectoryFinder->name('*.yml'); + $this->_testRootDirectoryFinder = $testRootDirectoryFinder; + } + + return $this->_testRootDirectoryFinder; + } + + protected function _getTestCaseRootDirectoryPath(): string + { + $reflectionClass = new ReflectionClass($this); + $testClassFilePath = $reflectionClass->getFileName(); + $testClassDirectoryPath = dirname($testClassFilePath); + $testCaseName = $this->getName(); + $testCaseRootDirectoryPath = $testClassDirectoryPath . '/' . $testCaseName; + + return $testCaseRootDirectoryPath; + } + + protected function _getContainerBuilderFacade(): Facade + { + if ($this->_containerBuilderFacade === null) { + $this->_containerBuilderFacade = Bootstrap::getContainerBuilderFacade(); + } + + return $this->_containerBuilderFacade; + } + + protected function getConnection() + { + $pdo = $this->_getContainerBuilderFacade()->getContainerBuilder()->get('pdo.builder')->getPdo(); + + return $this->createDefaultDBConnection($pdo); + } + + protected function getDataSet() + { + $fixturesDirectoryPath = $this->_getTestCaseRootDirectoryPath() . '/fixtures'; + $finder = new Finder(); + $finder->files()->in($fixturesDirectoryPath); + $finder->sortByName(); + foreach ($finder as $filePath => $file) { + $this->_addFilePathToYmlDataSet($filePath); + } + + return $this->_getEvaluatedYmlDataSet(); + } + + protected function _addFilePathToYmlDataSet(string $ymlDataSetFilePath): AbstractTest + { + if (!$this->_exists(YamlDataSet::class)) { + $ymlParser = new SymfonyYamlParser(); + $ymlParser->setFlags(Yaml::PARSE_CUSTOM_TAGS); + $this->_create(YamlDataSet::class, new YamlDataSet($ymlDataSetFilePath, $ymlParser)); + } else { + $this->_getYmlDataSet()->addYamlFile($ymlDataSetFilePath); + } + + return $this; + } + + protected function _getEvaluatedYmlDataSet(): YamlDataSet + { + /** @var DefaultTableIterator $tableIterator */ + $tableIterator = $this->_getYmlDataSet()->getIterator(); + $expressionLanguage = new ExpressionLanguage(); + $expressionValues = &$this->_getTestCaseService()->getExpressionValues(); + /** @var DefaultTable $table */ + foreach ($tableIterator as $table) { + $rowCount = $table->getRowCount(); + while (--$rowCount >= 0) { + $row = $table->getRow($rowCount); + foreach ($row as $columnName => $columnValue) { + if ($columnValue instanceof TaggedValue) { + if ($columnValue->getTag() === self::YML_SIGIL_PREFIX_FIXTURE_EXPRESSION) { + $expression = $columnValue->getValue(); + $expressedValue = $expressionLanguage->evaluate($expression, $expressionValues); + $table->setValue($rowCount, $columnName, $expressedValue); + } + } + } + } + } + + return $this->_getYmlDataSet(); + } + + protected function _getYmlDataSet(): YamlDataSet + { + return $this->_read(YamlDataSet::class); + } + + protected function _getTime(): TimeInterface + { + return $this->_getContainerBuilderFacade()->getContainerBuilder()->get('nhds.toolkit.time'); + } +} \ No newline at end of file diff --git a/scaffolding/src/Fixture/Expression/NumberPool.php b/scaffolding/src/Fixture/Expression/NumberPool.php new file mode 100644 index 00000000..18cae7c9 --- /dev/null +++ b/scaffolding/src/Fixture/Expression/NumberPool.php @@ -0,0 +1,54 @@ +isPoolInitialized($poolName)) { + $this->_initializePoolName($poolName); + } + + return $this->_nextNumberPool[$poolName]; + } + + public function advance(string $poolName): NumberPool + { + if (!$this->isPoolInitialized($poolName)) { + $this->_initializePoolName($poolName); + } + ++$this->_nextNumberPool[$poolName]; + + return $this; + } + + public function rewind(string $poolName): NumberPool + { + if (!$this->isPoolInitialized($poolName)) { + $this->_initializePoolName($poolName); + } + ++$this->_nextNumberPool[$poolName]; + + return $this; + } + + public function isPoolInitialized(string $poolName): bool + { + return isset($this->_nextNumberPool[$poolName]) ? true : false; + } + + protected function _initializePoolName(string $poolName): NumberPool + { + if (isset($this->_nextNumberPool[$poolName])) { + throw new \LogicException('Pool name is already initialized.'); + } + + $this->_nextNumberPool[$poolName] = 0; + + return $this; + } +} \ No newline at end of file diff --git a/scaffolding/src/Fixture/Expression/Value/AwareTrait.php b/scaffolding/src/Fixture/Expression/Value/AwareTrait.php new file mode 100644 index 00000000..bb1d321e --- /dev/null +++ b/scaffolding/src/Fixture/Expression/Value/AwareTrait.php @@ -0,0 +1,33 @@ +_expressionValues[$valueName])) { + throw new \LogicException('Expression value with value name "' . $valueName . '" is already set."'); + } + $this->_expressionValues[$valueName] = $value; + + return $this; + } + + public function hasExpressionValues(): bool + { + return empty($this->_expressionValues) ? false : true; + } + + public function &getExpressionValues(): array + { + if (empty($this->_expressionValues)) { + throw new \LogicException('Expression values is empty.'); + } + + return $this->_expressionValues; + } +} \ No newline at end of file diff --git a/scaffolding/src/PHPUnit/DbUnit/DataSet/SymfonyYamlParser.php b/scaffolding/src/PHPUnit/DbUnit/DataSet/SymfonyYamlParser.php new file mode 100644 index 00000000..c15f6d22 --- /dev/null +++ b/scaffolding/src/PHPUnit/DbUnit/DataSet/SymfonyYamlParser.php @@ -0,0 +1,31 @@ +_create(self::PROP_FLAGS, $flags); + + return $this; + } + + protected function _getFlags() + { + return $this->_read(self::PROP_FLAGS); + } + + public function parseYaml($yamlFile) + { + return Yaml::parse(\file_get_contents($yamlFile), $this->_getFlags()); + } +} \ No newline at end of file diff --git a/scaffolding/src/TestCase/ContainerBuilder/AwareTrait.php b/scaffolding/src/TestCase/ContainerBuilder/AwareTrait.php new file mode 100644 index 00000000..43405375 --- /dev/null +++ b/scaffolding/src/TestCase/ContainerBuilder/AwareTrait.php @@ -0,0 +1,38 @@ +_exists('test_container_builder')) { + $reflectionClass = new ReflectionClass($this); + $testClassFilePath = $reflectionClass->getFileName(); + $testClassDirectoryPath = dirname($testClassFilePath); + $shortName = $reflectionClass->getShortName(); + $testServicesYamlFilePath = $testClassDirectoryPath . '/config/' . $shortName . '.yml'; + $testContainerBuilder = new ContainerBuilder(); + $loader = new YamlFileLoader($testContainerBuilder, new FileLocator(__DIR__)); + $loader->load($testServicesYamlFilePath); + $passes = [new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass()]; + $repeatedPass = new RepeatedPass($passes); + $repeatedPass->process($testContainerBuilder); + $testContainerBuilder->set('test_container_builder', $testContainerBuilder); + $testContainerBuilder->compile(true); + $this->_create('test_container_builder', $testContainerBuilder); + } + + return $this->_read('test_container_builder'); + } +} \ No newline at end of file diff --git a/scaffolding/src/TestCase/Service.php b/scaffolding/src/TestCase/Service.php new file mode 100644 index 00000000..1fbe4f18 --- /dev/null +++ b/scaffolding/src/TestCase/Service.php @@ -0,0 +1,13 @@ +_testCaseService === null) { + $this->_testCaseService = $testCaseService; + }else { + throw new \LogicException('Test case service is already set.'); + } + + return $this; + } + + protected function _getTestCaseService(): TestCase\Service + { + if ($this->_testCaseService === null) { + throw new \LogicException('Test case service is not set.'); + } + + return $this->_testCaseService; + } +} \ No newline at end of file diff --git a/scaffolding/src/TestCase/ServiceInterface.php b/scaffolding/src/TestCase/ServiceInterface.php new file mode 100644 index 00000000..9b74d9c4 --- /dev/null +++ b/scaffolding/src/TestCase/ServiceInterface.php @@ -0,0 +1,8 @@ +_getContainerBuilderFacade()->getContainerBuilder()->get('selector'); } - protected function _getJobProcess(): JobInterface + protected function _getJobProcess(): WorkerInterface { - return $this->_getContainerBuilderFacade()->getContainerBuilder()->get('process.job'); + return $this->_getContainerBuilderFacade()->getContainerBuilder()->get('Worker'); } } \ No newline at end of file