Giter Site home page Giter Site logo

holisticon / ranked Goto Github PK

View Code? Open in Web Editor NEW
22.0 12.0 0.0 5.86 MB

Tracking kicker results

License: Other

Kotlin 42.48% Shell 0.08% HTML 1.58% JavaScript 0.75% CSS 10.34% TypeScript 44.62% Dockerfile 0.14%
kotlin spring-boot axon-framework ranking cqrs-es

ranked's Issues

Adopt Query Handlers

AxonFrameowrk 3.1 introduced QueryHandlers as components that typically read data from the view models created by the Event listeners. Add them into application.

Story: Rankings ELO

As a user I want to be abel to see rankings of all players in a particular discipline sorted by rank.
wireframe-ranking

The rank should be calculated not solely based on elo-ranking, but similar to tennis ranking in e.g. WTA.

UI: Allow to enter players after a match

If the players decide to start playing right away, there must be an option to specify the player names after a game in an intuitive manner.

Preferably the same UI, which is used to play the sets, is utilized.

docker-compose: players are initialized twice

I noticed the following when I do docker-compose up:

  • players are created
  • Processors are shut down ( Stopping Player: Shutdown state set for Processor 'Player'. Awaiting termination...)
  • players are re-created.

this does not cause a problem or duplicate values, but doesn't look nice.

user has image url

We want to display the user picture so the url to this image has to be stored when users are created.

Move configuration into RankedProperties

Currently, single properties ale loaded via @Value Spring Annotation and then gathered to a single properties object in order to pass around.

In order to improve readability of the code, implement @ConfigurationProperties-way using Kotlin.

Save sets in a heap

At the end of a match the frontend should send an array of MatchSets to the backend. Therefore we need to save the result of each set on a heap while playing a match.

Additionally we can fill the set counter with the current set number based on this heap.

Switch to Metadata for timestamps in events

Axon Frameowrk supplies metadata for fired events including the timestamp of event creation. Use this instead of polluting the command and event models with time information.

fix apiInfo swagger/springfox

I had to remove the apiInfo part from the Docket because after updating to springfox 2.7.0 it failed

 // TODO: had to remove this because it fails with 2.7.0 ... api changed
//    .apiInfo(ApiInfo(
//      "Ranked Command API",
//      "Command API to record new match results in ranked.",
//      "1.0.0",
//      "None",
//      Contact("Holisticon Craftsmen", "https://www.holisticon.de", "[email protected]"),
//      "Revised BSD License", "https://github.com/holisticon/ranked/blob/master/LICENSE.txt"))

Contact is no longer valid at that point

NPE when no sets are present

somehow, the sets are evaluated after the disjunct validation, which leads to NPE in the disjunct function

java.lang.NullPointerException: null
	at de.holisticon.ranked.command.api.CreateMatch$$EQbwrayu.disjunct(Commands.kt:53) ~[na:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
	at org.springsource.loaded.ri.ReloadedTypeInvoker$2.invoke(ReloadedTypeInvoker.java:133) ~[springloaded-1.2.8.RELEASE.jar:1.2.8.RELEASE]
	at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1462) ~[springloaded-1.2.8.RELEASE.jar:1.2.8.RELEASE]
	at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:120) ~[spring-expression-5.0.1.RELEASE.jar:5.0.1.RELEASE]

remove duplicate: model/ValidationMessages.properties

The update to kotlin 1.2.20 caused the bean validation test failed because the validation properties where not loaded from main/resources.

To temporarily fix this, the file was duplicated with 495b2ab

This should be removed again and fixed in a correct way.

Idea: maybe accessing resources in test/surefire changed?

Spring Configuration and CQRS

After a small discussion with @jangalinski we identified the following problem. A system configuration provided by properties file (application.yml) should not change the system behavior. In general this is a problem, because the properties are exactly made for this: change the behaviour of the application. Having no "current" state in the application makes it difficult to handle. Here is an example:

Imagine we configure the property of number of sets to win a set to 6. The matches created with this value are validated against this number and the corresponding events are stored. If this number changes (because we consider the new rules and play till 10), the events created with value 6 become invalid.

To handle this issue, ths configration must be held inside of an aggregate. A config change should be considered as a system command, and the aggregate may reject it, or send the corresponding events to the components.

UI: create match via rest

POST to

http://localhost:8081/command/createMatch (TODO: rename to /match)

to trigger axon creation of a match

Story: Game Result

As a player I want to record the result of a game.
As an example of a two vs. two kicker best-of-three up to 6 points page is depicted.
wireframe-game

use maven-oss-parent

replace the current spring boot parent with

    <groupId>io.toolisticon.maven</groupId>
    <artifactId>maven-oss-parent</artifactId>
    <version>0.4</version>
   <relativePath />   

view is empty after app-restart - replay tracking does not work

  • start h2-app, then ranked
  • create a match, verify its in wall-view and h2-domain
  • stop ranked - verify event still in h2
  • restart ranked -> view is empty (try manuall replay ... same result)
  • create match -> one match displayed in view, 2 events in h2

it really looks as if the replay (stop/delete token/start) does not work as expected ...

error on startup: primary key

2017-12-08 12:15:48.447 ERROR 61656 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : Eindeutiger Index oder Primärschlüssel verletzt: "UK8S1F994P4LA2IPB13ME2XQM1W_INDEX_8 ON PUBLIC.DOMAIN_EVENT_ENTRY(AGGREGATE_IDENTIFIER, SEQUENCE_NUMBER) VALUES ('kermit', 0, 1)"
Unique index or primary key violation: "UK8S1F994P4LA2IPB13ME2XQM1W_INDEX_8 ON PUBLIC.DOMAIN_EVENT_ENTRY(AGGREGATE_IDENTIFIER, SEQUENCE_NUMBER) VALUES ('kermit', 0, 1)"; SQL statement:
insert into domain_event_entry (event_identifier, meta_data, payload, payload_revision, payload_type, time_stamp, aggregate_identifier, sequence_number, type, global_index) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [23505-196]
2017-12-

Differentiate between type validation and domain validation

Validation of data is an important step towards prevention of errors and it should be executed as early as possible in the system. We use JSR330 Bean Validation to prevent wrong data from being entered into the system and put most of the data inside of the model classes, event classes and command classes.

Aparently, we have to be careful with validation constraints defined on the domain types, and separate them from rules defined through the domain aggregate logic.

Type constraints should be independent of the domain state and configuration - example, the score (=number of goals shot in the match) is a positive number or zero.

Domain constraints have a semantical meaning and may depend on domain configuration - example, the score to win a match at holisticon soccer is 6. It is wrong to put the validation of the score == 6 into domain type, because it is defined inside of our bounded context == aggregate, and is not defined in the domain.

P.S. if someone wants to define it inside the domain, it should be not ScoreToMinMatchSet, but something like HolisticonScoreToWinMatchSet - which makes a naming different and would be probably a bad domain type.

warnings in maven build: Kotlin.Int

I see this

[WARNING] ...\ranked\command\src\main\kotlin\Configuration.kt: (47, 39) This class shouldn't be used in Kotlin. Use kotlin.Int instead.
[WARNING] ...\ranked\command\src\main\kotlin\Configuration.kt: (50, 41) This class shouldn't be used in Kotlin. Use kotlin.Int instead.
[WARNING] ...\ranked\command\src\main\kotlin\Configuration.kt: (53, 36) This class shouldn't be used in Kotlin. Use kotlin.Int instead.
[WARNING] ...\ranked\command\src\main\kotlin\Rest.kt: (32, 11) Variable 'result' is never used
[WARNING] ...\ranked\command\src\main\kotlin\aggregate\Player.kt: (30, 36) This class shouldn't be used in Kotlin. Use kotlin.Int instead.

hikari/testdb - why do we have it - remove?

I saw on shutdown:

2017-11-10 22:15:04.375  INFO 50591 --- [       Thread-4] com.zaxxer.hikari.HikariDataSource       : testdb - Shutdown initiated...
2017-11-10 22:15:04.388  INFO 50591 --- [       Thread-4] com.zaxxer.hikari.HikariDataSource       : testdb - Shutdown completed.

testdb is the default in-mem db name, but we do not use it, we use localhost:9092/mem:ranked .

so why do we have testdb, how can we get rid of it, and is hikari (pooling) also used/usable for our tcp-db?

UI: Scroll of upside down components wrong in iOS

Seems like a technical iOS issue. When selecting the players for team red, the selection is upside down (like the player icons). In this situation the scroll on iOS is wrong, because it isn't rotated.

setup jackson-databind for kotlin

Warning in spring-boot start:

2017-12-08 10:34:55.016  WARN 57594 --- [ost-startStop-1] o.s.h.c.j.Jackson2ObjectMapperBuilder    : For Jackson Kotlin classes support please add "com.fasterxml.jackson.module:jackson-module-kotlin" to the classpath

spring-data-rest with swagger

at least for the h2-app it would be nice to use rest-jpa repos and have them in swagger as well ... this is supposed to work wie springfox 2.7 but fails with spring boot 2 (so far)

Remove MatchWinningSaga and adopt changes in the Aggregate

Currently Match Winning is an artificial construct to learn Sagas, but it feels like a smell, because it moves the logic of Match winning out of the match.

A better approach might be to calculate the match result inside of the Match Aggregate.

Cannot POST results

In the file frontend/src/main/js/pages:sendResults() I am sending the following POST to http://localhost:8080/command/match:

{ "teamRed":{ "player1":{ "value":"danielsteinhoefer" }, "player2":{ "value":"detlefvonderthuesen" } }, "teamBlue":{ "player1":{ "value":"lukastaake" }, "player2":{ "value":"leonfausten" } }, "matchSets":[ { "goalsRed":6, "goalsBlue":0, "offenseRed":{ "value":"danielsteinhoefer" }, "offenseBlue":{ "value":"lukastaake" } }, { "goalsRed":0, "goalsBlue":6, "offenseRed":{ "value":"detlefvonderthuesen" }, "offenseBlue":{ "value":"leonfausten" } } ], "type":"result" }

Unfortunately the validation fails with the following console output:

2018-01-26 16:11:48.431 WARN 65859 --- [nio-8081-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Missing type id when trying to resolve subtype of [simple type, class de.holisticon.ranked.model.AbstractMatchSet]: missing type id property 'type' (for POJO property 'matchSets'); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class de.holisticon.ranked.model.AbstractMatchSet]: missing type id property 'type' (for POJO property 'matchSets') at [Source: (PushbackInputStream); line: 1, column: 298] (through reference chain: de.holisticon.ranked.command.api.CreateMatch["matchSets"]->java.util.ArrayList[0])

update kotlin to 1.2.31

somehow the classloading changed, we get test failures for bean validation because validation messages are not resolved.
With kotlin 1.2.10 this still works.

see also: #45

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.