Generic Functionality

The following sections describe generic functionality that is available for all services.

Call statistics

Using the @Monitor annotation on a service-method will track call-statistics for this method. It will track (per deployment) the number of invocations, the maximum number of parallel invocations, and the min/average/max duration.

In case the duration exceeds one of two possible thresholds, a log-message and an event will be emitted. The emitted event contains details such as the component, service, method, requestId, duration, parameter-values, return-value, exception and duration-threshold. The events can be processed by an ELK-stack to provide insight into particularly slow or frequent calls and/or processes.

See the package com.trimplement.wallet.server.common.monitoring for more details.

Timestamp synchronization

Using the @TimestampSynchronized annotation on a service-method will ensure a single consistent java.util.Date in the TimestampHelper.asDate() method, which should then be used in favor of new Date(). This way, in case single process creates multiple entities or consists of multiple sub-processes, there is a single consistent timestamp available, e.g. for the creation-timestamps for the entities. Especially for processes around a day-boundary it is important to have a consistent timestamp, otherwise part of the process entities may have a creation-timestamp on different days/months/years.

The timestamp is set to the current timestamp upon the first @Timestamp annotation in the current request. The timestamp is thread-bound, and will remain the same for subsequent annotations.

See the package com.trimplement.wallet.server.common.timestamp for more details.

RequestIDs

The RequestIdHolder can be used to retrieve a globally unique id for the current request, which (when properly configured) is assigned to every API call and batch-job. This way each process can be identified in case it is required for analysis. The RequestId is emitted in the log files (as an MDC REQID) and is generated by a RequestIdGenerator, typically just before an API call is made (in com.trimplement.wallet.server.wallet.webapp.common.requestid.RequestIdHandlerInterceptor.preHandle()), or when a batch-job is starting (in com.trimplement.wallet.server.common.jobs.WalletQuartzJobBean.executeInternal()).

The RequestId is thread-bound.

See the package com.trimplement.wallet.server.common.requestid for more details.

Entry/exit logging

Using the @Log annotation on a service-implementation or service-method will emit entry and exit log messages for each public service-method, including parameter-values and return-value and exception, on the provided log-level. The annotation has several attributes that control what, when and how much is logged, e.g. the maximum length for a parameter-value, or to only log the number of elements in a return-value-list instead of all items.

If an exception passes multiple @Log annotations, it will only be logged at the first annotation it encounters, and will be suppressed on outer @Log annotations in the same thread.

See the package com.trimplement.wallet.server.common.logging for more details.

SecureString

The SecureString class is used to wrap a String, and mask it, and ensure it will never be unmasked unless explicitly requested, even in typical toString() situations, such as logging. This is typically used for sensitive data such as passwords, token-secrets, etc.

See com.trimplement.wallet.server.common.dom.SecureString for more details.

Money

The Money class is used to represent an amount and a currency. Instances are immutable, and it supports various operations, such as add, subtract, multiply, divide, round, truncate, etc.

Amounts are represented as BigDecimal, and the current database-representation supports up to 16 fractional digits and 20 regular digits (thus 36 in total, which should be sufficient for most amounts).

The currency is stored as a String, so it supports virtual currencies as well.

The actual currency configuration is managed by the Accounting component, and is not part of the Money object, which only contains the amount/currency.

InputValidator

The InputValidator class is used to validate input parameters and conditions in service-methods. It collects the validation-results using the check-methods, and throws an InvalidInputException containing the violations upon collectAndThrow(). There are various specific check-methods, e.g. for String and SecureString values, and a more generic checkThat() method that accepts any boolean expression as input.

See com.trimplement.wallet.server.common.service.InputValidator for more detail.

PublicId

The PublicIdConverter is used to generate a hard-to-guess public representation of an internal numerical id (typically a database-id). The default PublicId is a Base64-representation of a 42-byte array, based on a version, the masked id and a checksum using type-specific pre/post-fixes.

The goal of a PublicId is to have a public representation that is hard to guess, provides no visible information regarding to the value of the internal id, and contains a checksum to prevent using the id for an invalid entity.

The PublicIdConverter has a deployment-wide registry for converters per entity-type, so typically the entity-type is required to convert an internal-id to a public-id, and vice-versa.

See com.trimplement.wallet.server.common.service.PublicIdConverter for more details.

DisplayId

The DisplayIdConverter is similar to the PublicIdConverter, but allows for a shorter and thus more user/display-friendly id. By default the DisplayId equals the PublicId, but a product may override this behavior for certain entities.

See com.trimplement.wallet.server.common.service.DisplayIdConverter for more details.

ApiRequestInfo

The ApiRequestInfo contains context-information for the API call being made, and is required for every published non-anonymous internal-service-method. It contains data such as the request-URL, parameters, tokenId and token, the IP-address, the authenticated roles, whether the API call was public (ExternalAPI) or Admin (InternalAPI), etc.

A special instance of ApiRequestInfo can be created for running processes with a system-context, such as batch-jobs.

See com.trimplement.wallet.server.common.dom.ApiRequestInfo for more details.

Events

Through a LogEventPublisher the system may generate events. These events can be processed as required, by default they are written as a JSON-representation into a dedicated logger, so they can be consumed by an ELK-stack for further processing.

Typical events are slow calls, certain state-changes for certain entities (e.g. locking a wallet), periodical events that monitor JVM-resources, etc.

See the package com.trimplement.wallet.server.common.logging.publish for more details.

InitializingBean.afterPropertiesSet() usage restrictions

Do not use afterPropertiesSet() method with database operations, as it can lead to application startup failures when database is not available. If you need to initialize a service using information from database, use the resource monitoring approach. See Resource Monitoring section for further details.