...
Uses the concept of sessions to buckets in order to give a logical separation between different scopes. For example, "config" could be a bucket to store all data related to the configurations scope, and it will be represented as a folder in the local file system provider.
@Inject
protected BinaryDataService binaryDataService;
protected BinaryDataServiceSession session;
@PostConstruct
void init() {
session = binaryDataService.newSession("config");
}
public void storeConfig(String key, InputStream inputStream) {
session.store(key, inputStream);
}
public Optional<InputStream> findConfig(String key) {
return session.find(key);
}
...
Property | Type | Default | Description |
---|---|---|---|
initialCapacity | Integer | 16 | The minimum size of the cache |
maximumSize | Long | The maximum size of the cache. Can not be combined with a weigher | |
maximumWeight | Long | The maximum weight to be allowed for an element in the cache (see Weigher section) | |
expireAfterWrite | Duration | The time to wait to expire an element after its creation | |
expireAfterAccess | Duration | 5m | The time to wait to expire an element after the last time it was accessed |
recordStats | boolean | true | To record statistics about hit rates and evictions (see Cache Statistics section) |
testMode | boolean | false | To execute all cache operations in a single thread |
...
If the cache statistics are enabled, they will be published as part of the application metrics:
cache.eviction.weight
- the sum of weights of evicted entriescache.evictions
- the count of cache evictionscache.size
- the estimated number of entries in the cachecache.gets
- the number of times a cache-annotated method has returned an item (regardless if it was cached or not). This metric can be refined with the use of tags:result:hit
- the number of times cache lookup methods have returned a cached valueresult:miss
- the number of times cache lookup methods have returned an uncached value
...
Property | Type | Default | Description |
---|---|---|---|
maxCount | Integer | The maximum number of elements before flushing. Triggers a Count flush | |
maxDataSize | Long | The maximum size of the collection elements before flushing. Triggers a Data Size flush | |
flushAfter | Duration | The duration before flushing. Triggers a Scheduled flush | |
threads | Integer | 5 | The number of threads used to execute the flush event |
flushTimeout | Duration | 10m | The timeout for the flush event |
...
Function to determine the size of an element. Required to trigger a Data Size flush. For instance, a collection of integer elements can define its weigher as:
...
Consumer to be executed if the flush handler was successfully executed. For instance, a success handler for a collection of integer elements can be defined as:
...
BiConsumer to be executed if the flush handler failed. For instance, a failure handler for a collection of integer elements can be defined as:
...
Each collection will publish metrics about the duration of each flush event, its size, and the count of success/failures (see Metrics section).
This can be refined with the use of custom tags during the creation of the collection:
...
{
"or": [
{
"equals": {
"field": "fieldA",
"value": "valueA"
}
}, {
"equals": {
"field": "fieldB",
"value": "valueB"
}
}
]
}
EvalEx
EvalEx is a lightweight library capable of processing numeric, logical, conditional, String, array and structure-based expressions at runtime. It doesn’t need any external dependencies. Some minor functionalities such as support for hexadecimal and implicit multiplication are present. None of the functions are null safe due to the conversion of the parameters to EvaluationValue
during processing.
Example of basic expression evaluation without variables or configuration.
var input = "5 * 2";
var expression = new Expression(input);
var rawResult = expression.evaluate();
int finalResult = rawResult.getNumberValue().intValue();
If the expression has variables, a Map with the value of said variables must be provided.
var input = "x * y";
Map<String, Object> variables = new HashMap<>();
variables.put("x", "5");
variables.put("y", "2");
var expression = new Expression(input);
var rawResult = expression.withValues(variables).evaluate();
int finalResult = rawResult.getNumberValue().intValue();
Exceptions
The library provides two new exceptions which must be handled. A ParseException
is thrown, when the expression could not be parsed. An EvaluationException
is thrown, when the expression could be parsed, but not evaluated. If possible, both exceptions report the following details:
- Start Position of the error (character position, starting with 1).
- End Position of the error (character position, starting with 1).
- The Token string, usually the operator, function, variable or literal causing the error.
- The error message.
Default Functions
Although the default operators and functions are not explicitly listed in the official documentation, they can be seen in the ExpressionConfiguration
class.
Function | Description | Example |
---|---|---|
ABS | Returns the absolute value of a value | ABS(-7) = 7 |
CEILING | Rounds a number towards positive infinity | CEILING(1.1) = 2 |
FACT | Returns the factorial of a number | FACT(5) = 120 |
FLOOR | Rounds a number towards negative infinity | FLOOR(1.9) = 1 |
IF | Conditional operation where if the first parameter is true, the second one is executed. If not, the third parameter is executed | IF(TRUE, 5+1, 6+2) = 8 |
LOG | Performs the logarithm with base e on a value | LOG(5) = 1.609 |
LOG10 | Performs the logarithm with base 10 on a value | LOG10(5) = 0.698 |
MAX | Returns the highest value from all the parameters provided | MAX(5, 55, 6, 102) = 102 |
MIN | Returns the lowest value from all the parameters provided | MIN(5, 55, 6, 102) = 5 |
NOT | Negates a boolean expression | NOT(True) = false |
RANDOM | Returns random number between 0 and 1 | RANDOM() = 0.1613... |
ROUND | Rounds a decimal number to a specified scale | ROUND(0.5652,2) = 0.57 |
SUM | Returns the sum of the parameters | SUM(0.5, 3, 1) = 4.5 |
SQRT | Returns the square root of the value provided | SQRT(4) = 2 |
ACOS | Returns the arc-cosine in degrees | ACOS(1) = 0 |
ACOSH | Returns the hyperbolic arc-cosine in degrees | ACOSH(1.5) = 0.96 |
ACOSR | Returns the arc-cosine in radians | ACOSR(0.5) = 1.04 |
ACOT | Returns the arc-co-tangent in degrees | ACOT(1) = 45 |
ACOTH | Returns the hyperbolic arc-co-tangent in degrees | ACOTH(1.003) = 3.141 |
ACOTR | Returns the arc-co-tangent in radians | ACOTR(1) = 0.785 |
ASIN | Returns the arc-sine in degrees | ASIN(1) = 90 |
ASINH | Returns the hyperbolic arc-sine in degrees | ASINH(6.76) = 2.61 |
ASINR | Returns the arc-sine in radians | ASINR(1) = 1.57 |
ATAN | Returns the arc-tangent in degrees | ATAN(1) = 45 |
ATAN2 | Returns the angle of arc-tangent2 in degrees | ATAN2(1, 0) = 90 |
ATAN2R | Returns the angle of arc-tangent2 in radians | ATAN2R(1, 0) = 1.57 |
ATANH | Returns the hyperbolic arc-tangent in degrees | ATANH(0.5) = 0.54 |
ATANR | Returns the arc-tangent in radians | ATANR(1) = 0.78 |
COS | Returns the cosine in degrees | COS(180) = -1 |
COSH | Returns the hyperbolic cosine in degrees | COSH(PI) = 11.591 |
COSR | Returns the cosine in radians | COSR(PI) = -1 |
COT | Returns the co-tangent in degrees | COT(45) = 1 |
COTH | Returns the hyperbolic co-tangent in degrees | COTH(PI) = 1.003 |
COTR | Returns the co-tangent in radians | COTR(0.785) = 1 |
CSC | Returns the co-secant in degrees | CSC(270) = -1 |
CSCH | Returns the hyperbolic co-secant in degrees | CSCH(3*PI/2) = 0.017 |
CSCR | Returns the co-secant in radians | CSCR(3*PI/2) = -1 |
DEG | Converts an angle from radians to degrees | DEG(0.785) = 45 |
RAD | Converts an angle from degrees to radians | RAD(45) = 0.785 |
SIN | Returns the sine in degrees | SIN(150) = 0.5 |
SINH | Returns the hyperbolic sine in degrees | SINH(2.61) = 6.762 |
SINR | Returns the sine in radians | SINR(2.61) = 0.5 |
SEC | Returns the secant in degrees | SEC(120) = -2 |
SECH | Returns the hyperbolic secant in degrees | SECH(2.09) = 0.243 |
SECR | Returns the secant in radians | SECR(2.09) = -2 |
TAN | Returns the tangent in degrees | TAN(360) = 0 |
TANH | Returns the hyperbolic tangent in degrees | TANH(2*PI) = 1 |
TANR | Returns the tangent in radians | TANR(2*PI) = 0 |
STR_CONTAINS | Returns true if string contains substring or false if not (case sensitive) | STR_CONTAINS("Hoy es", "Hoy") = true |
STR_LOWER | Converts all the characters of a string to upper case | STR_LOWER("HOY ES") = hoy es |
STR_UPPER | Converts all the characters of a string to upper case | STR_UPPER("hoy es") = HOY ES |
Expression Configuration
The expression evaluation can be configured to enable and disable specific features.
Feature | Description | Defaults |
---|---|---|
allowOverwriteConstants | Allows variables to have the name of a constant | True |
arraysAllowed | Allows array index functions | True |
dataAccessorSupplier | The Data Accessor is responsible for storing and retrieving variable values. You can define your own data access interface, by defining a class that implements the DataAccessorInterface | MapBasedDataAccessor |
decimalPlacesRounding | Specifies the amount of decimal places to round to in each operation or function | Disabled |
defaultConstants | Specifies the default constants that can be used in every expression | ExpressionConfiguration.StandardConstants |
functionDictionary | The function dictionary is used to look up the functions that are used in an expression. You can define your own function directory, by defining a class that implements the FunctionDictionaryIfc | MapBasedFunctionDictionary |
implicitMultiplicationAllowed | Allows for automatic multiplication without operators | True |
mathContext | Specifies the precision and rounding method | Precision: 68, Mode: HALF-EVEN |
operatorDictionary | The operator dictionary is used to look up the functions that are used in an expression. You can define your own operator directory, by defining a class that implements the OperatorDictionaryIfc | MapBasedOperatorDictionary |
powerOfPrecedence | Allows changes to the operation precedence | Lower precedence |
stripTrailingZeros | Allows the trailing decimal zeros in a number result to be stripped | True |
structuresAllowed | Specifies if the structure separator (‘.’) operator is allowed | True |
Custom Functions
Personalized functions can be added with the expression configuration. For this process a new class that extends AbstractFunction. In this class @FunctionParameter
tags must be added to class. These will signify the parameters needed to use the function. Lastly, an override to the evaluate method is needed to implement the custom function's logic. This functions can be called recursively.
This class is an example of a basic custom function which adds 5 to the parameter provided.
@FunctionParameter(name = "value")
public class AddFiveFunction extends AbstractFunction {
@Override
public EvaluationValue evaluate(Expression expression, Token functionToken, EvaluationValue... parameterValues) throws EvaluationException {
EvaluationValue value = parameterValues[0];
return new EvaluationValue(value.getNumberValue().doubleValue()+5.0);
}
}
The function is then added to the evaluated expression via an ExpressionConfiguration
object at evaluation time.
ExpressionConfiguration configuration = ExpressionConfiguration.
defaultConfiguration().withAdditionalFunctions(
Map.entry("ADDFIVE", new AddFiveFunction()));
var input = "ADDFIVE(5)";
var expression = new Expression(input, configuration);
var rawResult = expression.evaluate();
int finalResult = rawResult.getNumberValue().intValue();
Custom Operators
Much like functions, custom operators can be added. To do this, a new class that extends AbstractOperator
is needed. A tag must be added to specify if the operator must be used as prefix, postfix or infix. The tag also specifies the precedence using a value for comparison. The value of the other operators can be seen in the OperatorIfc
for reference. If no value is specified, the operator will have the highest precedence.
This class is an example of a basic custom function which adds 5 to the parameter provided.
@PrefixOperator(precedence = 1)
public class TimesThreeOperator extends AbstractOperator {
@Override
public EvaluationValue evaluate(Expression expression, Token operatorToken, EvaluationValue... operands) throws EvaluationException {
return new EvaluationValue(operands[0].getNumberValue().intValue()*3);
}
}
The operator is then added to the evaluated expression via an ExpressionConfiguration
object at evaluation time.
ExpressionConfiguration configuration = ExpressionConfiguration.
defaultConfiguration().withAdditionalOperators(
Map.entry("@", new TimesThreeOperator()));
var input = "@3";
Expression expression = new Expression(input, configuration);
return expression.evaluate();
EvalEx Utils
The EvalExUtils
class contains methods made to facilitate the processes that may use the Expression Language evaluator.
Array Converters
When an array is evaluated all of its contents are converted to an EvaluationValue
object. This renders the resulting array useless if not processed. To simplify this, 4 array converters were included to convert an EvaluationValue
array to an Integer, String, Boolean or plain Object array.
Added Functions
System Function
SystemFunction
gets a System property or Environment Variable value given it's key. The System property has precedence. If no System property or Environment variable is found, an EvaluationException
is thrown with the message "No such system parameter or environment variable". It is used with the SYSTEM
tag. E.g. SYSTEM(java.runtime.version) = 17.0.6+10 (result may vary).
Encrypt and Decrypt Functions
EncryptFunction
encrypts the given content using the encryption method in CryptoUtils
. It is used with the ENCRYPT
tag. E.g. ENCRYPT("Test") = (Encrypted string for "Test"). DecryptFunction
decrypts an encrypted content using the decryption method in CryptoUtils
. It is used with the DECRYPT
tag. E.g. DECRYPT(Encrypted string for "Test") = Test.
Regex Match Function
RegexMatchFunction
returns a boolean specifying if a string matches a given pattern. It is used with the REGEX_MATCH
tag. E.g. REGEX_MATCH("This is a Test", ".t") = true.
Ends With and Starts with Functions
EndsWithFunction
verifies with a boolean if a string ends with a given substring. It is used with the STR_ENDSWITH
tag. E.g. STR_ENDSWITH("This is a test","test") = true. StartsWithFunction
verifies with a boolean if a string starts with a given substring. These functions are case-sensitive. It is used with the STR_STARTSWITH
tag. E.g. STR_STARTSWITH("This is a test","This") = true.
Is Empty and Is Blank Functions
IsBlankFuction
verifies with a boolean if a string is blank. It is used with the tag STR_ISBLANK
tag. E.g. STR_ISBLANK(" ") = true. IsEmptyFunction
verifies with a boolean if a string is empty. It is used with the tag STR_ISEMPTY
tag. E.g. STR_ISEMPTY("") = true.
Split Function
SplitFunction
splits a given string by a given token. The resulting array contains EvaluationValue
objects, therefore the substrings must be converted back to strings. It is used with the STR_SPLIT
tag. E.g. STR_SPLIT("This is a Test", "") = {"This", "is", "a", "test"}.
Concat Function
ConcatFunction
concatenates any given set of strings. It is used with the STR_CONCAT
tag. E.g. STR_CONCAT("This", "is", "a", "test") = "This is a Test".
Array Join Function
ArrayJoinFunction
concatenates two given arrays of the same type into one array. It is used with the ARR_JOIN
tag. The resulting array will be an Object[], therefore it must be processed with the arrayFactoryProcessor
. E.g. JOIN(list1, list2) = (1, 2, 3, 4, 5, 6) with list1 = (1, 2, 3) and list2 = (4, 5, 6) being variables.
Array Contains Function
ArrayContainsFunction
verifies if an array contains a given value. It is used with the ARR_CONTAINS
tag. E.g. ARR_CONTAINS(array, 1) = true, with array = (1, 2, 3) being a variable.
Get By Index Function
GetByIndexFunction
provides the value in the given index. It is used with the ARR_GET
tag. E.g. ARR_GET(array, 0) = "This", with array = ("This", "is", "a", "test") being a variable.
Array Is Empty Function
ArrayIsEmptyFunction
provides a boolean specifying if an array is Empty. It is used with the ARR_ISEMPTY
tag. E.g. ARR_ISEMPTY(array) = true, with array = () being a variable.
Array Size Function
ArraySizeFunction
provides the value in the given index. It is used with the ARR_SIZE
tag. E.g. SIZE(array) = 3, with array = (1, 2, 3) being a variable.
HTTP Base Client
The HTTP Base Client is an abstraction of the OkHttpClient. It provides features such as retry handlers (see Retries) and automated paginated requests.
...
Property | Type | Default | Description |
---|---|---|---|
body | byte[] | The body of the message. | |
queue | String | The queue this message was sent to or delivered from. | |
type | Message.MessageType | The type of the message. Can be DIRECT or BROADCAST. See Message Types. | |
properties | Map<String,String> | Map of message properties. |
...
Parameter | Type | Description |
---|---|---|
queue | String | Name of the queue to register the Consumer to. |
consumerProperties | ConsumerProperties | A ConsumerProperties instance for the consumer. |
messageType | Message.MessageType | The type of message this consumer is supposed to listen to. Can be Message.MessageType.DIRECT or Message.MessageType.BROADCAST. See Message Types. |
onMessageDelivery | Predicate<Message> | The function to execute when a message is received. Returns true if the message is successfully consumed, false otherwise. |
...
Parameter | Type | Description |
---|---|---|
message | Message | The Message to send. |
successHandler | Consumer<Message> | A consumer function to execute when the message is succesfully sent. |
failureHandler | BiConsumer<Message, Exception> | A biconsumer function to execute when there is an error sending the message and the retries have been exhausted. |
...
Parameter | Type | Description |
---|---|---|
message | Message | The Message to send. |
Providers
RabbitMQ
...