0

I have a laravel 5.7 application where I want to add prooph for event sourcing. I have follow the instructions but I retrieve this error:

Prooph\ServiceBus\Exception\RuntimeException: CommandBus was not able to identify a CommandHandler for command App\src\Prooph\Model\Procedure\Command\ChangeProcedureState in /var/www/html/vendor/prooph/service-bus/src/CommandBus.php:58

This is my config/prooph.php file

return [
    'event_store' => [
        'adapter' => [
            'type' => \Prooph\EventStore\Pdo\MySqlEventStore::class,
            'options' => [
                'connection_alias' => 'laravel.connections.pdo',
            ],
        ],
        'plugins' => [
            \Prooph\EventStoreBusBridge\EventPublisher::class,
            \Prooph\EventStoreBusBridge\TransactionManager::class,
        ],
        'procedure_collection' => [
            'repository_class' => App\src\Prooph\Infrastructure\Repository\EventStoreProcedureCollection::class,
            'aggregate_type' => App\src\Prooph\Model\Procedure\Procedure::class,
        ],
    ],
    'service_bus' => [
        'command_bus' => [
            'router' => [
                'type' => \Prooph\ServiceBus\Plugin\Router\CommandRouter::class,
                'routes' => [
                    // list of commands with corresponding command handler
                    \App\src\Prooph\Model\Procedure\Command\ChangeProcedureState::class => App\src\Prooph\Model\Procedure\Handler\ChangeProcedureStateHandler::class,
                ],
            ],
        ],
        'event_bus' => [
            'plugins' => [
                \Prooph\ServiceBus\Plugin\InvokeStrategy\OnEventStrategy::class,
            ],
            'router' => [
                'routes' => [
                    // list of events with a list of projectors
                ],
            ],
        ],
        /*'event_bus' => [
            'router' => [
                'routes' => [
                    // list of events with a list of projectors
                    App\src\Prooph\ProophessorDo\Model\User\Event\UserWasRegistered::class => [
                        \App\src\Prooph\ProophessorDo\Projection\User\UserProjector::class
                    ],
                ],
            ],
        ],*/
    ],
];

This is my service that dispatch the command

class ProcedureRetrieveStateChanged
{
    /** @var \FluentProceduresRepository $procedureRepository */
    private $procedureRepository;
    /**
     * @var CommandBus
     */
    private $commandBus;

    public function __construct(\FluentProceduresRepository $procedureRepository, CommandBus $commandBus)
    {
        $this->procedureRepository = $procedureRepository;
        $this->commandBus = $commandBus;
    }

    public function execute($procedureId, array $groups)
    {
        $procedure = $this->procedureRepository->find($procedureId);

        if (null === $procedure) {
            return false;
        }

        foreach ($groups as $group) {
            $actualState = $procedure->getStatebyGroup($group['pivot']['group_id']);

            if ($actualState !== $group['pivot']['state']) {
                $command = new ChangeProcedureState(
                    [
                        'procedure_id' => $procedureId,
                        'group_id' => $group['pivot']['group_id'],
                        'old_state' => $actualState,
                        'new_state' => $group['pivot']['state'],
                    ]
                );

                $this->commandBus->dispatch($command);

            }
        }
    }
}

This is my command

final class ChangeProcedureState extends Command implements PayloadConstructable
{
    use PayloadTrait;

    public function procedureId(): ProcedureId
    {
        return ProcedureId::fromString($this->payload['procedure_id']);
    }

    public function state(): string
    {
        return $this->payload['state'];
    }

    protected function setPayload(array $payload): void
    {
        Assertion::keyExists($payload, 'procedure_id');
        Assertion::keyExists($payload, 'group_id');
        Assertion::keyExists($payload, 'old_state');
        Assertion::keyExists($payload, 'new_state');

        $this->payload = $payload;
    }
}

And this is my handler

class ChangeProcedureStateHandler
{
    /**
     * @var ProcedureCollection
     */
    private $procedureCollection;

    public function __construct(ProcedureCollection $procedureCollection)
    {
        $this->procedureCollection = $procedureCollection;
    }

    public function __invoke(ChangeProcedureState $command): void
    {
        $procedure = $this->procedureCollection->get($command->procedureId());
        $procedure->changeState($command->state());

        $this->procedureCollection->save($procedure);
    }
}

Can someone help me with this problem?

Alessandro Minoccheri
  • 35,521
  • 22
  • 122
  • 171
  • Code looks good so far, but the command router is missing the route. How is the command bus set up in your Laravel app? – Alexander Miertsch Nov 21 '18 at 06:23
  • how to setup the command bus? I think it's that the problem @AlexanderMiertsch – Alessandro Minoccheri Nov 22 '18 at 08:13
  • Are you using prooph/laravel-package ? Maybe you should create an issue there. Here is a laravel version of proophessor-do: https://github.com/camuthig/proophessor-do-laravel the command bus is set up using a factory provided by prooph/service-bus. – Alexander Miertsch Nov 22 '18 at 17:02
  • What happens if you use the command bus facade provided by laravel package: CommandBus::dispatch($command) in ProcedureRetrieveStateChanged – Alexander Miertsch Nov 22 '18 at 17:07

1 Answers1

0

To use handlers as a string you need to use ServiceLocatorPlugin, but before that you need to register all handlers in laravel container, like $app->singletor...or $app->bind.

Cheers.

e.bezdomnikov
  • 115
  • 1
  • 7