-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
356 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
<?php | ||
/* | ||
* This file is part of the prooph/service-bus. | ||
* (c) Alexander Miertsch <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
* | ||
* Date: 30.10.14 - 22:29 | ||
*/ | ||
|
||
namespace Prooph\ServiceBus\Router; | ||
|
||
use Prooph\ServiceBus\Exception\RuntimeException; | ||
use Prooph\ServiceBus\Process\CommandDispatch; | ||
use Prooph\ServiceBus\Process\EventDispatch; | ||
use Zend\EventManager\AbstractListenerAggregate; | ||
use Zend\EventManager\EventManagerInterface; | ||
|
||
/** | ||
* Class RegexRouter | ||
* | ||
* @package Prooph\ServiceBus\Router | ||
* @author Alexander Miertsch <[email protected]> | ||
*/ | ||
class RegexRouter extends AbstractListenerAggregate | ||
{ | ||
const ALL = '/.*/'; | ||
|
||
/** | ||
* @var array[array[pattern => handler], ...] | ||
*/ | ||
protected $patternMap = array(); | ||
|
||
/** | ||
* @var string | ||
*/ | ||
protected $tmpPattern; | ||
|
||
/** | ||
* @param null|array[pattern => handler|handler[]] $patternMap | ||
*/ | ||
public function __construct(array $patternMap = null) | ||
{ | ||
if (! is_null($patternMap)) { | ||
foreach ($patternMap as $pattern => $handler) { | ||
if (is_array($handler)) { | ||
foreach($handler as $singleHandler) $this->route($pattern)->to($singleHandler); | ||
} else { | ||
$this->route($pattern)->to($handler); | ||
} | ||
|
||
} | ||
} | ||
} | ||
|
||
/** | ||
* implementation will pass this to the aggregate. | ||
* | ||
* @param EventManagerInterface $events | ||
* | ||
* @return void | ||
*/ | ||
public function attach(EventManagerInterface $events) | ||
{ | ||
$identifiers = $events->getIdentifiers(); | ||
|
||
if (in_array('command_bus', $identifiers)) { | ||
$this->listeners[] = $events->attach(CommandDispatch::ROUTE, array($this, 'onRouteCommand'), 100); | ||
} | ||
|
||
if (in_array('event_bus', $identifiers)) { | ||
$this->listeners[] = $events->attach(EventDispatch::ROUTE, array($this, 'onRouteEvent'), 100); | ||
} | ||
} | ||
|
||
/** | ||
* @param string $pattern | ||
* @return $this | ||
* @throws \Prooph\ServiceBus\Exception\RuntimeException | ||
*/ | ||
public function route($pattern) | ||
{ | ||
\Assert\that($pattern)->notEmpty()->string(); | ||
|
||
if (! is_null($this->tmpPattern)) { | ||
throw new RuntimeException(sprintf("pattern %s is not mapped to a handler.", $this->tmpPattern)); | ||
} | ||
|
||
$this->tmpPattern = $pattern; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @param string|object|callable $handler | ||
* @return $this | ||
* @throws \Prooph\ServiceBus\Exception\RuntimeException | ||
* @throws \InvalidArgumentException | ||
*/ | ||
public function to($handler) | ||
{ | ||
if (! is_string($handler) && ! is_object($handler) && ! is_callable($handler)) { | ||
throw new \InvalidArgumentException(sprintf( | ||
"Invalid handler provided. Expected type is string, object or callable but type of %s given.", | ||
gettype($handler) | ||
)); | ||
} | ||
|
||
if (is_null($this->tmpPattern)) { | ||
throw new RuntimeException(sprintf( | ||
"Cannot map handler %s to a pattern. Please use method route before calling method to", | ||
(is_object($handler))? get_class($handler) : (is_string($handler))? $handler : gettype($handler) | ||
)); | ||
} | ||
|
||
$this->patternMap[] = [$this->tmpPattern => $handler]; | ||
|
||
$this->tmpPattern = null; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @param CommandDispatch $commandDispatch | ||
* @throws \Prooph\ServiceBus\Exception\RuntimeException | ||
*/ | ||
public function onRouteCommand(CommandDispatch $commandDispatch) | ||
{ | ||
if (is_null($commandDispatch->getCommandName())) { | ||
$commandDispatch->getLogger()->notice( | ||
sprintf("%s: CommandDispatch contains no command name", get_called_class()) | ||
); | ||
return; | ||
} | ||
|
||
$alreadyMatched = false; | ||
|
||
foreach($this->patternMap as $map) { | ||
list($pattern, $handler) = each($map); | ||
if (preg_match($pattern, $commandDispatch->getCommandName())) { | ||
|
||
if ($alreadyMatched) { | ||
throw new RuntimeException(sprintf( | ||
"Multiple handlers detected for command %s. The patterns %s and %s matches both", | ||
$commandDispatch->getCommandName(), | ||
$alreadyMatched, | ||
$pattern | ||
)); | ||
} else { | ||
$commandDispatch->setCommandHandler($handler); | ||
$alreadyMatched = $pattern; | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @param EventDispatch $eventDispatch | ||
*/ | ||
public function onRouteEvent(EventDispatch $eventDispatch) | ||
{ | ||
if (is_null($eventDispatch->getEventName())) { | ||
$eventDispatch->getLogger()->notice( | ||
sprintf("%s: EventDispatch contains no event name", get_called_class()) | ||
); | ||
return; | ||
} | ||
|
||
foreach($this->patternMap as $map) { | ||
list($pattern, $handler) = each($map); | ||
if (preg_match($pattern, $eventDispatch->getEventName())) { | ||
$eventDispatch->addEventListener($handler); | ||
} | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.