Backend is based primarily on the Spring and Activiti workflow technologies.
Going from the bottom:
Entity (AbstractEntity) ⇒ repository (AbstractEntityRepository) ⇒ service (AbstractReadWriteEntityService) ⇒ REST (DefaultReadWriteEntityController).
Creating a child of each one of the classes above is sufficient for issuing a new REST endpoint for the new agenda (entity).
And now in a bit more detail …
We are expecting to use the relational databese through a jdbc connector. Primarily, we are going to use PosgreSQL
and h2
for demo purposes (e.g. the default spring profile is going to be connected to h2, so that nothing would need to be configured after downloading the application from Git and the application would work properly after deploying to Tomcat). Spring profiles for the individual supported databases will be created. There is going to be a set of database scripts (create + change scripts) for each database. We expect use the flyway tool for their administration.
Using of Hibernate is a logical choice, nothing changes/ will change about that. We will keep creating entities
which will map relational database tables into java classes. Moreover, entities will be supplemented with jsr303
(@NotNull, @Email ..) validation annotations, which will be automatically validated (and finally the validation propagated to REST). In combination with using Spring Data and REST (see below), annotations for json de/serialization will be added as well. The entity and its scheme will gain more importance in the new BE because if the special mapping is not stated in dto (ResourceProcessor), it will flow through the entire application via projection (see Spring Data REST below).
Setting the cache selectively for the individual operations: https://spring.io/blog/2015/06/15/cache-auto-configuration-in-spring-boot-1-3
The application is superordinate to the spring boot platform and, besides the core functions, it uses a number of spring frameworks, libraries and procedures:
Spring Data facilitates the work with the (not only) relational database. The data can be accessed simply by issuing the interface according to certain conventions. I find this being combined with the securing through annotations and the possibility of adding SpEl expressions into queries very strong.
Intended extensions: - support of searching through standard jpa criteria for more difficult queries via Querydsl
Issues Spring Data repositories via REST interface.
Advantages:
Disadvantages:
@RepositoryRestControllery
to make use of some of the advantages of spring data REST (patch method, json mapping, converters) and, at the same time, to be able to add a service layer. Nevertheless, the non-existence of dtos is still a problem because we would like to add more metadata (e.g. ui information) to the REST endpoints and create a service layer for a proper API.
The Spring Data layer, REST or services themselves can be supplemented with annotations evaluating security (before or after calling). A logged-in user can be used favorably as an input for search queries (e.g. queries like "give me subordinates"). The SpEl expressions are used in the annotations, so that is will be possible to create and call any function which decides whether someone has or does not have a right for something.
Authorities (hasAuthority), not roles themselves, will be used for evaluating the target permissions. Similarly to the previous backend, there is a configuration of individual authorities (permissions) with each role. When an identity is assigned a role, the identity acquires the target authorities. Authorities are returned at login as a unique list of base permissions (e.g. USER_READ) ⇒ the authorities are available in the user's security context.
To make assigning permissions to a role easier the following interfaces are created:
BasePermission
- base permissions (e.g. READ, WRITE …)GroupPermision
- group (target) permission (e.g. USER, ROLE …)Assigning permissions to a role is represented by this pair:
When evaluating, target and action acts as an authority target_action (e.g. USER_READ).
Each module can register its own set of permissions (both a new group, and adding new base permissions to an already existing group).
Each role has its own type (system, business, technical … ) according to application settings.
Roles can be assembled into a composition.
We have chosen Activiti BPM Platform as our workflow engine. It is a widely-used workflow engine, which focuses mainly on the speed and simplicity of usage for developers. Its main purpose is controlling and executing procedures described using the BPMN 2.0 language in Java.
One of the advantages is its integration with Spring framework and therefore its easier application in our devstack. Activiti Platform allows us to issue a REST interface through which most functions can be controlled, i.e. it is possible to have Activiti Platform + REST interface running on the application server and communicate with it even from a non-Java environment. A disadvantage of this solution is the loss of direct Java integration, i.e. the possibility of calling Spring beans directly from a workflow process (using Expression Language), which considerably extends the potential of the workflow and speeds up development.
We expect to use optimistic locks on key entities. Auxiliary entities will not be locked - the last to come is the winner. If needed, it will be possible to engage an optimistic lock on any entity. The use of pessimistic locks is not expected yet.
Regarding the user interface, the ETag
and LastModified
headings are planned to be used for informing the user about changes made by somebody else in his currently edited log + a mechanism for using my changes or reloading the changed log.
The solution assumes that the objects will not be kept loaded (outside of the UI) for long in order not to break the optimistic log. At the same time, it is necessary to keep the transaction processing over the object being changed.
Optimistic lock is engaged on entities:
TODO: Guest, system …
TODO: Rules for contributors, approving requests, etc. (to be studied)
Application profiles configured:
default
- the default profile - configured to db h2. If a developer downloads the project from Git and builds, the application will run without any other configuration over h2 database with demo data (by admin user …).Either a new profile will be configured, or the default one will be used for issuing a demo ⇒ it will be practically identical.
TODO: It suggests itself that when building backend we could also add frontend and when deploying the war?, FE would also run normally. Then we could just put war? on an application server and it's done :)