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.