Skip to content

08. Concepts

Schubert, Stefan edited this page Dec 19, 2022 · 16 revisions

8.1 Domain Models

8.2 Recurring or Generic Structures and Patterns

  • 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.

8.3 Persistence

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.

8.3.1 Flyway

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.

8.4 User Interface

8.5 Ergonomics

8.6 Flow of Control

8.7 Transaction Procession

8.8 Session Handling

None

The solution is build upon REST principles. The server won't keep sessions.

8.9 Security

8.9.1 REST-IDs will be obfuscated.

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.

8.9.2 JWT Token Handling

We use the following Endpoint Security as configured in WebSecurityConfig.java

Allow Welcome Page

  • /
  • /index.html

Allow Swagger api-doc access

  • /v3/api-docs

Registration and Login are accessible without JWT based authentication

  • /api/auth/login
  • /api/auth/register
  • /api/auth/req_pwd_reset
  • /api/auth/email/**

Open statistics without JWT based authentication

  • /api/stats/healthcheck

All others require JWT authentication

8.10 Safety

8.11 Communications and Integration with other Software Systems

8.12 Distribution

8.13 Plausibility and Validity Checks

8.14 Exception/Error Handling

8.15 System Management and Administration

8.16 Logging, Tracing

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

Usage of log-levels:

  • 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);

Configuration

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.

8.17 Business Rules

8.18 Configurability

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.

8.19 Parallelization and Threading

8.20 Internationalization (i18n)

8.20.1 Context JSF WebApp

UTF-8 Encoding of property files

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.

Location of message properties

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.

8.21 Migration

8.22 Testability

8.23 Scaling, Clustering

8.24 High Availability

8.25 Code Generation

8.26 Build-Management

Clone this wiki locally