Giter Site home page Giter Site logo

prooph / proophessor-do-symfony Goto Github PK

View Code? Open in Web Editor NEW
170.0 27.0 53.0 4.59 MB

Symfony version of proophessor-do CQRS + Event Sourcing example app

Home Page: http://getprooph.org/

License: Other

PHP 22.57% HTML 3.51% CSS 1.01% JavaScript 72.68% Shell 0.05% Makefile 0.17%

proophessor-do-symfony's Introduction

Proophessor Do Symfony

prooph components in action

Build Status Gitter

Proophessor Do Symfony (short Do) demonstrates the power of prooph components in conjunction with Symfony (with Flex enabled).

This is a clone of proophessor-do to demonstrate the Symfony way with prooph components.

Business Domain

The business logic implemented in this educational project is very simple and should be known by everybody in one way or the other. It is about managing todo lists for users whereby a todo can have a deadline and the assigned user can add a reminder to get notified when time has passed.

Installation

Please refer to the installation instructions.

If you have problems with cache files run sudo chmod -R 777 var

Running the app with Docker

docker-compose up -d

Management UI

Information about the Management UI can be found in the original proophessor-do repo:

Management UI Documentation

Model Exploration

Learning by doing!

Check proophessor-do for open tasks and more information.

We want to merge the different framework variants of our learning application to make it easier for people to work on a task using their favorite web framework. Check out the corresponding issue

Support

Happy messaging!

proophessor-do-symfony's People

Contributors

basz avatar christian-kolb avatar codeliner avatar coudenysj avatar darrylhein avatar dave-redfern avatar dragosprotung avatar iamlucianojr avatar izayoi256 avatar mbadolato avatar nek- avatar patrick-blom avatar prolic avatar rabbl avatar renan-taranto avatar sandrokeil avatar tobemedia avatar ufomelkor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

proophessor-do-symfony's Issues

Symfony Flex issue

When run the command to install composer dependencies

docker run --rm -it --volume $(pwd):/app prooph/composer:7.1 install -o --prefer-dist

I got this error message

Declaration of Symfony\Flex\ParallelDownloader::getRemoteContents($originUrl, $fileUrl, $context) should be compatible with Composer\Util\RemoteFilesystem::getRemoteContents(...

I solved updating Symfony Flex

docker run --rm -it --volume $(pwd):/app prooph/composer:7.1 update symfony/flex --no-scripts

and then tun again the composer dependencies installation.
I think is worth it to insert this update into the installation process

How to switch to async command and event routers?

There is no example to switch routers to async with Symfony configuration.

I want to implement a custom MessageProducer and a consumer based on symfony/messenger. But I don’t find any doc about wiring them into the Prooph Service-bus.

I tried to enable async_switch on my default command bus but the __invoke method is never called.

# config/packages/prooph_service_bus.yaml
command_buses:
     default_command_bus:
            router:
                async_switch: 'async_message_producer'
                type: 'prooph_service_bus.command_bus_router'
#services.yaml
services:
    _defaults:
        autowire: true
        autoconfigure: true 
        public: false  

    async_message_producer:
        class: App\ServiceBus\Model\AsyncMessageProducer
        public: true

why so many problems

fisrt problem, i have fixed it by converting string to boolean tpye
image

second problem. why the option of swiftmailer is url?
image
image

third problem. why can i not found Symfony\Component\DependencyInjection? which version should be installed?
image

maybe there are many other problems will to be resolved. Do not you check this repo's correctness?

Installing with Docker now working

I'm following instructions. EventStore and tables were created but seems projections are not.

`An exception occurred while executing 'SELECT * FROM read_user':

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'todo.read_user' doesn't exist`

Error related to make during install

I'm trying to setup the docker version, but I get the following when running:

 docker run --rm -it --volume $(pwd):/app prooph/composer:7.1 install -o --prefer-dist

I get the following:

 [KO] Script make cache-warmup returned with error code 127 
 !! sh: make: not found 
 !!

Continuing to follow the docker instructions it does seem to work.

I'm on Mac OS 10.13.4. I have installed Xcode & additional tools.

From what I can find, it's can't find make. When I do which make I get /usr/bin/make so apparently make is installed.

Cannot autowire service "Prooph\ProophessorDo\Model\User\Service\ChecksUniqueUsersEmailAddress"

(1/1) RuntimeException
Cannot autowire service "Prooph\ProophessorDo\Model\User\Service\ChecksUniqueUsersEmailAddress": argument "$userFinder" of method "Prooph\ProophessorDo\Infrastructure\Service\ChecksUniqueUsersEmailAddressFromReadModel::__construct()" references class "Prooph\ProophessorDo\Projection\User\UserFinder" but no such service exists. You should maybe alias this class to the existing "proophdo.todo_projection.user_finder" service.

Todo's with duplicate id possible?

public function __invoke(PostTodo $command): void
{
$user = $this->userCollection->get($command->assigneeId());
if (! $user) {
throw UserNotFound::withUserId($command->assigneeId());
}
$todo = $user->postTodo($command->text(), $command->todoId());
$this->todoList->save($todo);
}

Maybe I'm overlooking something, but shouldn't this also check to see whether a Todo with the TodoId in the Command already exists?

Finish rewrite

TODO

from #13

  • Update README and Docs
  • Get rid of templating component, see #13 (review)
  • Test different installation ways
  • Release new bundle versions and require them in the demo
  • Reactivate reminder email service
  • Test process managers (not working atm)
  • Enable snapshots and snapshot projection
  • Merge prooph-do and prooph-do-symfony

Merge this repo into proophessor-do

Directory structure something like this:

- install
    - src
- zend-expressive
    - bin
    - config
    - public
    - src
    - templates
    - ...
- symfony
    - bin
    - config
    - public
    - src
    - templates
    - ...
- src
    - Model
    - ProcessManager
    - Projection
    - ...
- tests
    - Symfony
    - Expressive
    - ProophessorDo
- vendor

In the install directory we should have some composer install scripts, similar to what is at https://github.com/zendframework/zend-expressive-skeleton/

The installer asks something like:
What framework you want to use?
a) symfony
b) zend-expressive
c) both

and so on, which installs additional composer packages.

This will reduce maintenance overhead (f.e. a bugfix or feature in proophessor-do src doesn't need to get applied to two repositories) and people also have an app where they can have a direct framework comparision.

The latest mysql version 8 may cause issue

/var/www # bin/console event-store:event-stream:create

In AbstractMySQLDriver.php line 121:
An exception occurred in driver: SQLSTATE[HY000] [2054] The server requeste
d authentication method unknown to the client

In PDOConnection.php line 47:
SQLSTATE[HY000] [2054] The server requested authentication method unknown t
o the client

In PDOConnection.php line 43:
SQLSTATE[HY000] [2054] The server requested authentication method unknown t
o the client

In PDOConnection.php line 43:
PDO::__construct(): The server requested authentication method unknown to t
he client [caching_sha2_password]


Solution:
The docker composer by default using the latest mysql version which is 8 now. I specified version in docker-composer.yml and it worked.

mysql:
image: mysql:5

Duplcate key violation while create projections

I've noticed several times "stream position" in table "projections" is less then expected (I've got unique constraint violation i my read table when event proceed twice).

To reproduce a bug I've added a simple console command

adapik@4dfe0be

To run it just run bin/console test:run

It fills event store with events. Now when running bin/console event-store:projection:run user_projection or bin/console event-store:projection:run todo_projection I've got a DBAL Exception:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'a82d2b4c-878f-4aaa-8827-03eed2fe56ae' for key 'PRIMARY'

It happens rather randomly in time, but in all cases in table projections position counter is less then nr of event which has been created the last read model entry.

QueryBus with null handler

I'm having problems dispatching a QueryBus, the handler is resolved as an empty string, then my process is finished but not handler

Vagrant setup is broken

The vagrant setup is broken. I found multiple issues so consider updating the vagrant and docker setup to fit the prooph/proophessor-do configuration. Alternatively we could fix the issues in this repo by it think it´s better to get in sync with the base repo.

  • vagrant provision fails with "the input device is not a TTY" => remove "-i" argument from the docker run calls to get rid of
  • can't open 'bin/setup_mysql.sh' => the file does not exist
  • build prod assets during vagrant provisioning or change url in "docs/installation/vagrant.md" to /app_dev.php
  • run the doctrine migrations during vagrant provision

I´m gonna provide a pull request fixing some of the listed issues, but as mentioned in #6 a better concept is needed.

Can not dispatch QueryBus to Handler

Settings

prooph_service_bus:
  command_buses:
    default_command_bus: ~

  query_buses:
    default_query_bus: ~

services:
  # default configuration for services in *this* file
  _defaults:
    # automatically injects dependencies in your services
    autowire: true
    # automatically registers your services as commands, event subscribers, etc.
    autoconfigure: true
    # this means you cannot fetch services directly from the container via $container->get()
    # if you need to do this, you can override this setting on individual services
    public: false

  Query\Handler\GetUserListHandler:
    public: true
    tags:
        - { name: 'prooph_service_bus.default_query_bus.route_target' }

Controller

use Prooph\ServiceBus\QueryBus;
...
 $this->queryBus->dispatch(
            new GetUserList()
        )->done(
            function($result) {
                \dump($result);
            },
            function($error) {
                \dump($error);
            }
        ) ;

Command has anything. Handler has one method:

 public function __invoke(GetUserList $query, Deferred $deferred)
    {
        $i = random_int(1, 2);
        if ($i % 2 === 0) {
            $deferred->resolve('DONE!');
        }
            $deferred->reject('Out of luck');
    }

ERROR

MessageDispatchException {#167303 ▼
  #actionEvent: null
  #message: "Message dispatch failed. See previous exception for details."
  #code: 422
  #file: "/var/www/site/vendor/prooph/service-bus/src/Exception/MessageDispatchException.php"
  #line: 26
  -previous: RuntimeException {#167300 ▼
    #message: "Query Query\UseCase\GetUserList was not handled"
    #code: 0
    #file: "/var/www/site/vendor/prooph/service-bus/src/QueryBus.php"
    #line: 103
    trace: {▶}
  }
  trace: {▶}
}

Ok, lets try xml settings

<service id="Prooph\ServiceBus\QueryBus" alias="prooph_service_bus.default_query_bus"/>
 <service id="Query\Handler\GetUserListHandler"
                 class="Query\Handler\GetUserListHandler"
                 public="true">
            <tag name="prooph_service_bus.default_query_bus.route_target" message_detection="true"/>
        </service>

and

        <service id="Query\Handler\GetUserListHandler"
                 class="Handler\GetUserListHandler"
                 public="true"
        >
            <tag name="prooph_service_bus.default_query_bus.route_target" 
                 message_detection="Query\UseCase\GetUserList"
                 // or
                 message_detection="true"
            />
        </service>

Same error.

Remove any settings at all and try as in example from video https://www.youtube.com/watch?v=6EcQjVSj3m4

 $queryRouter = new QueryRouter();
        $queryRouter->route(GetUserList::class)->to( GetUserListHandler::class);
        $queryRouter->attachToMessageBus($this->queryBus);

        $this->queryBus->dispatch(
            new GetUserList(
                $filter,
                $pagination,
                $order
            )
        )->done(
            function($result) {
                \dump($result);
            },
            function($error) {
                \dump($error);
            },
            function($progress) {
                \dump($progress);
            }
        )

Still no luck, same error. Why it is not handled? Let us take a look log file

Initialized query message
--> message-data: {  }
--> message-name: null
--> message-handled: false
--> message-handler: ''
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Detect query message name for Query\UseCase\GetUserList
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: ''
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Detect query message route for Query\UseCase\GetUserList
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Locate query handler for Query\UseCase\GetUserList
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Dispatching query Query\UseCase\GetUserList to handler
  Query\Handler\GetUserListHandler
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Finished query: "Query\UseCase\GetUserList" by handler
Query\Handler\GetUserListHandler
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus

Strange, handler found and defined, we have method but it still not handeld, why?
Lets try to pass object, but we do not want and need to pass object, because we have to use constructor when Handler invoked, to manage dependencies.

Changes:

$queryRouter->route(GetUserList::class)->to( new GetUserListHandler());

And THIS IS IT! IT WORKS! Let us see log and what the difference between working and not working samples


Initialized query message
--> message-data: {  }
--> message-name: null
--> message-handled: false
--> message-handler: ''
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Detect query message name for Query\UseCase\GetUserList
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: ''
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Detect query message route for Query\UseCase\GetUserList
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Locate query handler for Query\UseCase\GetUserList
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Dispatching query Query\UseCase\GetUserList to handler
  Query\Handler\GetUserListHandler
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: false
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus
___ QUERY_BUS.DEFAULT_QUERY_BUS ____________________________________________________________________
Finished query: "Query\UseCase\GetUserList" by handler
  Query\Handler\GetUserListHandler
--> message-data: {  }
--> message-name: Query\UseCase\GetUserList
--> message-handled: true
--> message-handler: Query\Handler\GetUserListHandler
--> bus-type: query
--> bus-name: default_query_bus

No difference. Help me please to register Handler in xml service and make it work without every time using

  $queryRouter = new QueryRouter();
        $queryRouter->route(GetUserList::class)->to( new GetUserListHandler());
        $queryRouter->attachToMessageBus($this->queryBus);

We have to initialize dependencies in constructor somehow and avoid such boilerplate like above.

In tactician we were using simply

 <service id="League\Tactician\CommandBus" alias="tactician.commandbus.default"/>
        <service id="GetSingleUserHandler" class="Query\Handler\GetUserListHandler">
            <tag name="tactician.handler" typehints="true"/>
        </service>
<service id="Prooph\ServiceBus\Plugin\Router\SingleHandlerRouter"
                 class="Prooph\ServiceBus\Plugin\Router\SingleHandlerRouter"
        >
            <argument type="collection" key="$messageMap">
                <argument key="Query\UseCase\GetUserList">Query\Handler\GetUserListHandler</argument>
            </argument>
        </service>

//and
  <service id="Query\Handler\GetUserListHandler"
                 class="Query\Handler\GetUserListHandler"
        >
            <tag name="prooph_service_bus.query_buses.default_query_bus.route_target"
                 message="Query\UseCase\GetUserList"
            />
        </service>
  <service id="Query\Handler\GetUserListHandler"
                 class="Query\Handler\GetUserListHandler"
        >
            <tag name="prooph_service_bus.query_buses.default_query_bus.route_target"
                 message_detection="true"
            />
        </service>

Will return

MessageDispatchException {#3249 ▼
  #actionEvent: null
  #message: "Message dispatch failed. See previous exception for details."
  #code: 422
  #file: "/var/www/grabgg/vendor/prooph/service-bus/src/Exception/MessageDispatchException.php"
  #line: 26
  -previous: RuntimeException {#3246 ▼
    #message: "QueryBus was not able to identify a Finder for query App\Application\CQRS\User\Query\UseCase\GetUserList"
    #code: 0

I think it may be wrong tab and wrong repository for that issue sorry.

Can be close, found issue

     <service id="GetUserListHandler"  <<-------- HERE id must be different
                 class="App\Application\CQRS\User\Query\Handler\GetUserListHandler"
        >
            <tag name="prooph_service_bus.default_query_bus.route_target"
                 message="App\Application\CQRS\User\Query\UseCase\GetUserList"
            />
        </service>

But please note issue with examples. Maybe docs update? And video with example seems to be outdated. ALso, message_detection does not work for me. "QueryBus was not able to identify a Finder for query " when

  <tag name="prooph_service_bus.default_query_bus.route_target"
                 message_detection="true"
            />

Only "message" works

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.