-
Notifications
You must be signed in to change notification settings - Fork 3
08. Concepts
- The JSF Webclient follows an MVC Pattern.
- Using of transport-objects to decouple from persistence model.
- Factory-Patterns for managing testdata.
- Test-Suite hierarchy to manage junits.
We are using JPA managed Entities in combination with SpringData Repositories, which are responsible to manage all CRUD and other persistence operations. Instead of using classic JPA DAOs the usage of SpringData Repositories spares a lot of boilerplate-code and speeds up the development of required CRUD functionality, while still offering the flexibility to tune SQL for performance reasons if required.
The intention of the persistence layer to isolate the application from the datalayer, through which we are allowed to do persistence refactorings (e.g. for performance’s sake) without mingling with the object models used on the client site. Or in other words, we are able to evolve data and application layer independently.
Our persistence layer is being kept in de.bluewhale.sabi.persistence of the sabi-server module.
To control and ease database evolution in a possible shared team, we are using flyway. Meaning it is not allowed to update sql scripts which already have run in production, instead developers are forced to write proper migration scripts. As a maintenance engineer you have also more control to see, which script has been rolled out.
The solution is build upon REST principles. The server won't keep sessions.
All objectIds that are presented to the outside world will be obfuscated, so that we do not have an attack vector just by increment the id (e.g.) of a user to do bad things.
We use the following Endpoint Security as configured in WebSecurityConfig.java
- /
- /index.html
- /v3/api-docs
- /api/auth/login
- /api/auth/register
- /api/auth/req_pwd_reset
- /api/auth/email/**
- /api/stats/healthcheck
We are using Spring-Boot with log4j.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
static Logger logger = LoggerFactory.getLogger(AuthenticationController.class);
...
logger.error("What went wrong",e);
The default will log onto the console. Since the application (sabi) is being deployed and run as a system service, all logging on the console will go into /var/log/sabi.log
-
DEBUG: Used for verbose logging for live debugging on certain program flows.
-
INFO: Use this for things you would like to count in your log-files like business metrics. Or when you will see that a use case has been executed (at some point).
-
WARN: If a use-case does not go the "all is good" flow, but is still resilient due to proper error handling. Meaning e.g. the user will be able to retry, by fixing a parameter like username if it already exists during registration.
-
ERROR: If a use-case enters a state which was not intended (IOExceptions) and will be aborted. Error Handling results more in "Something went wrong and the user has no chance to deal with the situation". The throwable needs to be logged too. So here you use the: logger.error("What went wrong",e);
The logging configuration can be done within the application.properties file with the following key/values:
Flag which can be checked before doing debug logging at all:
debug = true
Setting the desired loglevel (DEBUG|INFO|WARN|ERROR):
logging.level.root = WARN
In case you wish to omit the console logging and go to a specific file instead:
logging.path = /var/tmp/
logging.file = mylog.log
Note − files will rotate automatically after reaching the size 10 MB.
We are using spring boots mechanisms of application.properties (in the yml version). The default one (with development environment settings) can be found in its standard place src/resources.
For production, we use an external application.yml which then contains all the secrets. For this we this deployment layout:
sabi
| sabi-backend.jar
| config
| application.yml
spring will see it by default and use this setting to overwrite the defaults of /src/resources.
At 08/2019 UTF-8 encoding of property files is not supported through the used JSF resource bundle mechanism, though spring would do it. See https://github.com/joinfaces/joinfaces/issues/720 I decided against switching to Springs EL and adding the bean-hack on my own, since the research alone of what went wrong was too time-consuming, and I hope that a solution might be available with java9 through one of the next JoinFaces versions. In the meantime the workaround is that UTF-8 characters will be encoded in ISO-8859-1 with the help of my favorite IDE - which may be a disadvantage if someone joins the project which IDE does not do the trick.
Though we are using joinfaces to integrate with spring which configure all static web pages to we located in
src
|- main
| |- java
| |- resources
| | |- META-INF
| | | |- resources
| | | | *.xhtml
The property resolver follows the spring convention, which expects the message bundle here:
src
|- main
| |- java
| |- resources
| | | messages.properties
This looks ugly as we are using two different resource folders, but as I haven't found to reconfigure them we stick to the default configuration. To make clear which files belog to i18n in this resource folder, we use an i18n SubDir. So our layout looks like this:
src
|- main
| |- java
| |- resources
| | |- i18n
| | | | messages.properties
| | | | messages_de.properties
| | | | messages_en.properties
The following snippet from a xhtml file shows how to access the translations:
<f:loadBundle basename="i18n.messages" var="msg"/>
<h:form id="login-form" prependId="false">
<p:panel header="#{msg['login.h.header']} (#{applicationInfo.version})">
...
Please have a look into the messages.properties file which contains the description of a naming convention for the properties.
In case you want to know: All diagrams were generated with plantuml. The diagrams source code has been checked in, just have a look into the sabi-server/UML directory.