Build, test, deploy

Trace-X is built using Maven and utilizes all the standard concepts of it. Test execution is part of the build process and a minimum test coverage of 80% is enforced.

The project setup contains a multi-module Maven build. Commonly used classes (like the Trace-X data model) should be extracted into a separate submodule and reused across the project. However, this is not a "one-size-fits-all" solution. New submodules should be created with care and require a review by the team.

The Maven build alone only leads up to the JAR artifact of Trace-X. To create Docker images, the Docker build feature is used. This copies all resources into a builder image, builds the software and creates a final Docker image at the end that can then be deployed.

Although the Docker image can be deployed in various ways, the standard solution are the provided Helm charts, which describe the required components as well.

Code generation

There are two methods of code generation in Trace-X:

Lombok

The Lombok library is heavily used to generate boilerplate code (like constructors, getters, setters, builders…​). This way, code can be written faster and this boilerplate code is excluded from test coverage, which keeps the test base lean.

Swagger / OpenAPI

The API uses OpenAPI annotations to describe the endpoints with all necessary information. The annotations are then used to automatically generate the OpenAPI specification file, which can be viewed in the Swagger UI that is deployed with the application.

The generated OpenAPI specification file is automatically compared to a fixed, stored version of it to avoid unwanted changes of the API.

Migration

Data migration is handled by flyway.

Configurability

Trace-X utilizes the configuration mechanism provided by Spring Boot. Configuration properties can be defined in the file src/main/resources/application.yml

Other profiles should be avoided. Instead, the configuration can be overwritten using Spring’s external configuration mechanism (see https://docs.spring.io/spring-boot/docs/2.1.9.RELEASE/reference/html/boot-features-external-config.html). The operator must have total control over the configuration of Trace-X.

Java style guide

We generally follow the Google Java Style Guide.

API guide

We generally follow the OpenAPI Specification.

Docomentation style guide

Unit and functional testing

General unit testing

  • Code coverage >= 80%

  • Writing methods which provide a response to be better testable (avoid void if feasible).

  • Naming of unit tests are as follows:

unit test naming
  • Use given/when/then pattern for unit test structuring. E.g:

given when then pattern

Integration testing

Each public API should have at least two integration tests (positive / negative). For integration testing, the tx-backend/src/main/resources/application-integration.yml is used. Additionally, you need to have a local Docker environment running. For this, we recommend Rancher Dektop.

Clean code

We follow the rules and behaviour of: https://clean-code-developer.com/.

Secure coding standards

As there is no other guideline of C-X, we fix any vulnerabilities, exposures, flaw detected by one of our SAST, DAST, Pentesting tools which is higher than "Very Low".

vulnerability level

Trace-X technical class responsibilities

Controller

  • Has only one dependency to a facade or a service or a validator annotation

  • Has no own logic

  • Includes the swagger documentation annotations

  • Has an integration test class

  • Uses a static mapper to transform a domain model into the response model

  • Returns a ResponseEntity<T>

Response object

  • Should be a public version of the domain object

  • Is a result of the transformation which will be done in the facade

  • Is not necessary if the domain object can be fully public

  • Is not allowed to be implemented in a repository or a DAO

Facade

  • Should have multiple service classes injected

  • Can be implemented in a controller

ServiceImpl

  • Responsible for retrieving data from storage

  • Performs business logic

  • Can be a http client

  • Returns a jpaEntity → domain object

  • Should only be implemented in a controller through an interface

Repository

  • Represents an interface to the underlying repository implementation which then uses the spring repository

Domain object

  • Mapped from an entity or from received external data

  • Will be used as a working model until it will finally be transformed to a response object or another domain which will be persisted later on

Config object

  • Should have the suffix .config at the end of the class

  • Includes beans which are automatically created by app startup

Constructing objects

  • Using builder pattern

    • Currently, we are using the constructor to create objects in our application. Main reason is to provide immutable objects.

    • As the handling with big loaded constructors is not easy and error prone, it’s recommended to use the builder pattern to have a clear understanding about what we are creating at the point of implementation.

  • Using lombok for annotation processing