/** * Allow * * Link a Class (probably a handler) to a handler! * Note that we actually __allow__ a class to read/write to a bus. * * If you want the same class to listen to multiple bussystems then re-call route!! * * Example: * * route( 'system-bus', 'handler-1' ) * route( 'system-bus', 'handler-2' ) * route( 'system-err', 'handler-1' ) * route( 'system-err', 'handler-2' ) * ... * * Have a look into the example Handlers which use Annotations map commands * * - - - - - - - - - - - - - - - - - - - * * + class MockBarHandler * ** * * @command Test\Mock\Command\MockCommand * * * public function getBar($command) * - - - - - - - - - - - - - - - - - - - * * @param BusInterface $bus * @param String $qualifiedClassname * @throws AdapterException */ private function allow(BusInterface $bus, $qualifiedClassname) { if (!class_exists($qualifiedClassname)) { throw AdapterException::initializeError(sprintf('Class <%s> does not exist', $qualifiedClassname)); } $reflClass = new \ReflectionClass($qualifiedClassname); $reflMs = $reflClass->getMethods(); foreach ($reflMs as $reflM) { if (preg_match_all('~@(command|event|query)\\s+(\\S+)~i', $reflM->getDocComment(), $annotations, PREG_SET_ORDER) > 0) { foreach ($annotations as $class) { $qualifiedClassname = $class[2]; if (false === class_exists($qualifiedClassname)) { throw AdapterException::annotationError(sprintf('Class <%s> does not exist', $qualifiedClassname)); } if (isset(class_implements($qualifiedClassname)['Malocher\\Cqrs\\Command\\CommandInterface'])) { $bus->mapCommand($qualifiedClassname, array('alias' => $reflM->class, 'method' => $reflM->name)); } if (isset(class_implements($qualifiedClassname)['Malocher\\Cqrs\\Event\\EventInterface'])) { $bus->registerEventListener($qualifiedClassname, array('alias' => $reflM->class, 'method' => $reflM->name)); } if (isset(class_implements($qualifiedClassname)['Malocher\\Cqrs\\Query\\QueryInterface'])) { $bus->mapQuery($qualifiedClassname, array('alias' => $reflM->class, 'method' => $reflM->name)); } } } } }
/** * */ public function testGetBus() { $bus = $this->getBus(); $this->assertEquals($this->bus, $bus); $anotherBus = $this->getBus('test-coverage-mock-another-bus'); $this->assertEquals($this->anotherBus->getName(), $anotherBus->getName()); }
/** * Initialize (pipe) a bus via configuration file! * * @param BusInterface $bus * @param array $configuration * @throws AdapterException */ public function pipe(BusInterface $bus, array $configuration) { foreach ($configuration as $messageClass => $callableOrDefinition) { if (!class_exists($messageClass)) { throw AdapterException::initializeError(sprintf('Message class <%s> does not exist', $messageClass)); } else { if ($this->isCommand($messageClass)) { $bus->mapCommand($messageClass, $callableOrDefinition); } else { if ($this->isEvent($messageClass)) { $bus->registerEventListener($messageClass, $callableOrDefinition); } else { if ($this->isQuery($messageClass)) { $bus->mapQuery($messageClass, $callableOrDefinition); } else { throw AdapterException::pipeError(sprintf('Message <%s> must implement %s, %s or %s', $messageClass, 'Malocher\\Cqrs\\Command\\CommandInterface', 'Malocher\\Cqrs\\Query\\QueryInterface', 'Malocher\\Cqrs\\Event\\EventInterface')); } } } } } }
/** * {@inheritDoc} */ public function publishEvent(EventInterface $event) { // Check if event exists after invoking the PublishEventCommand because // the PublishEventCommand tells that a event is dispatched but does not care // if it succeeded. Later the EventPublishedEvent can be used to check if a // event succeeded. if (!is_null($this->gate->getSystemBus())) { $publishEventCommand = new PublishEventCommand(); $publishEventCommand->setMessageClass(get_class($event)); $publishEventCommand->setMessageVars($event->getMessageVars()); $publishEventCommand->setBusName($this->getName()); $this->gate->getSystemBus()->invokeCommand($publishEventCommand); } try { $response = $this->bus->publishEvent($event); if ($response === false) { return false; } } catch (BusException $ex) { //throw it again throw $ex; } catch (\Exception $ex) { throw BusException::defaultBusError($ex->getMessage(), null, $ex); } // Dispatch the EventPublishedEvent here! If for example a event could not be dispatched // because it does not exist in the eventListenerMap[<empty>] this Event would never // be dispatched! if (!is_null($this->gate->getSystemBus())) { $eventPublishedEvent = new EventPublishedEvent(); $eventPublishedEvent->setMessageClass(get_class($event)); $eventPublishedEvent->setMessageVars($event->getMessageVars()); $eventPublishedEvent->setBusName($this->getName()); $this->gate->getSystemBus()->publishEvent($eventPublishedEvent); } return $response; }
/** * attach bus * * @param BusInterface $bus * @throws Gate\GateException */ public function attach(BusInterface $bus) { $bus->setGate($this); if ($bus->getName() == AbstractBus::SYSTEMBUS) { if (!$bus instanceof SystemBus) { throw GateException::attachError(sprintf('Bus <%s> is reserved!', $bus->getName())); } if (!is_null($this->systemBus)) { throw GateException::attachError('SystemBus is already attached!'); } $this->systemBus = $bus; return; } if (isset($this->buses[$bus->getName()])) { throw GateException::attachError(sprintf('Bus <%s> is already attached!', $bus->getName())); } $proxy = new BusProxy($bus); $proxy->setGate($this); $this->buses[$bus->getName()] = $proxy; }