Message
Events traversing layline.io Workflows are instantiated as a Message. This class exposes a number of properties and methods to extract and set data within messages.
To understand the anatomy of a message please read the respective chapter in the documentation.
Example Message Structure
Assume we have the following data dictionary structure
- Header
- IOT
- RECORD_TYPE
- DEVICE_NO
- IOT
- Detail
- IOT
- RECORD_TYPE
- TIME
- MEASUREMENT
- IOT
- Trailer
- IOT
- RECORD_TYPE
- COUNT
- IOT
Then in a Javascript processor we can do this:
...
export function onMessage() {
if (message.typeName === 'Header') {
onHeader (message);
} else if (message.typeName === 'Detail') {
onDetail(message);
} else if (message.typeName === 'Trailer') {
onDetail(message);
}
// send the message on through OUTPUT_PORT of Processor
stream.emit(message, OUTPUT_PORT);
}
...
And this:
...
// Handle a detail record type
function onDetail (message) {
const m = message.data.IOT.MEASUREMENT;
const VENDOR = Status.getVendorByName('MyVendorLongName');
if (m < 0) {
message.addStatus(Severity.ERROR, Status.create(VENDOR, 'ILLEGAL_MEASUREMENT', m));
}
}
...
Properties
data
data:
Object
The data of the message. It is a nested object structure that reflects the structure of the data dictionary of this message.
Example
// Create Detail
const detailMessage = dataDictionary.createMessage(dataDictionary.type.Detail);
detailMessage.data.PRODUCT = {
RECORD_TYPE : "D",
ID : message.data.Id,
CODE : message.data.Code,
NAME : message.data.Name,
CATEGORY : message.data.Category,
PRICE : message.data.Price,
STOCK_QUANTITY : message.data.StockQuantity,
COLOR : message.data.Color,
LAUNCH_DATE : message.data.LaunchDate,
}
// stream.logInfo(f"detailMessage: {detailMessage.toJson()})")
stream.emit(detailMessage, OUTPUT_PORT);
id
id:
string
The unique identifier of the message. This is a consecutive number starting with "1" for the first message. It is used to uniquely identify a message within a stream. Cloning a message will generate a new id, whereas the original message will keep its id and the cloned message will have the original message number appended by a "." and a new consecutive number. For example, "1.1", "1.2", "1.3", ... for each clone of the original message.
Example
// Accessing the id of a message
const id = message.id;
typeName
typeName:
string
The type name of the message. This is the name of the data dictionary type that the message represents.
Example
const typeName = message.typeName;
// e.g, If in your data dictionary you have a type called "MyType", then this will return "MyType"
if (message.typeName === 'MyType') {
// do something
}
Methods
addStatus()
addStatus(
severity,status,addToLog?):void
Adds a Status to a message. The Status must have been created with Status.create or otherwise instantiated.
Parameters
severity
Severity value.
status
The Status which should be added.
addToLog?
boolean = true
Signals whether the Status shall also be added to the log, or not. Will be added by default if not specified.
If true then the Status will be visible in the Stream Log of the Audit Trail.
Returns
void
Example
if (error) {
message.addStatus(Severity.ERROR, Status.create(VENDOR, 'ILLEGAL_VALUE', valueString));
}
clone()
clone():
Message
Creates a full clone of a Message
clonedMessage = message.clone();
Returns
Message
A copy of a Message
commit()
commit():
Message
Commits the message, typically used with message queues or streaming platforms.
This method is used to acknowledge the successful processing of a message. The exact behavior depends on the underlying system:
- For an SQS queue, it deletes the message from the queue.
- For a Kafka topic, it commits the offset of the consumer.
Calling this method indicates that the message has been successfully processed and should not be redelivered.
Returns
Message
Returns the message instance for method chaining.
Example
export function onMessage() {
try {
// Process the message
const result = processMessage(message);
if (result.success) {
// If processing was successful, commit the message
message.commit();
print("Message processed and committed successfully");
} else {
print("Message processing failed, not committing");
}
} catch (error) {
print("Error processing message:", error);
// In case of an error, you might choose not to commit
// so that the message can be reprocessed
}
}
function processMessage(msg) {
// Implement your message processing logic here
// Return an object indicating success or failure
}
exists()
exists(
type):boolean
Checks if a known data structure is recognized within a given Message. Data structures are spawned into existence by the definition of data formats (Format Assets). You can test a particular Message on whether a specific structure is present within a message by using this method.
This is typically used to check whether a message is of a certain type, or not.
Parameters
type
Path to data dictionary structure which you want to test for existence in the message (DataDictionaryEntity.)
Returns
boolean
True, if it exists, else false.
Example
// Get the access path to a structure within the compiled data dictionary
const MY_RECORD_TYPE = dataDictionary.type.MyFormat.Detail;
// Test message against the existence of the data dictionary structure.
if (message.exists(MY_RECORD_TYPE)) {
...
}
findStatus()
findStatus(
value):Status[]
Finds and returns an array of status entries attached to the message based on the provided filter.
This method allows you to search for status entries using three different approaches:
- By Vendor: Find all statuses from a specific vendor.
- By Severity: Find all statuses of a specific severity level.
- By Custom Function: Use a custom filter function to find statuses based on any criteria.
Parameters
value
Vendor | Severity | ((status) => boolean)
The filter to apply:
- If a Vendor is provided, it returns all statuses from that vendor.
- If a Severity is provided, it returns all statuses of that severity level.
- If a function is provided, it should take a Status as input and return a boolean.
The method will return all statuses for which this function returns
true.
Returns
Status[]
An array of Status objects that match the provided filter. Returns an empty array if no matching statuses are found.
Examples
// Finding statuses by Vendor
const VENDOR = Status.getVendorByName('MyVendorName');
const vendorStatuses = message.findStatus(VENDOR);
vendorStatuses.forEach(status => {
print(`Found status: ${status.code} - ${status.message}`);
});
// Finding statuses by Severity
const errorStatuses = message.findStatus(Severity.ERROR);
if (errorStatuses.length > 0) {
print(`Message has ${errorStatuses.length} error statuses`);
}
// Finding statuses using a custom filter function
function hasSpecificCode(status) {
return status.code === "SPECIFIC_CODE";
}
const specificStatuses = message.findStatus(hasSpecificCode);
specificStatuses.forEach(status => {
print(`Found status with specific code: ${status.message}`);
});
// Using an arrow function for filtering
const highPriorityStatuses = message.findStatus(s => [Severity.WARNING, Severity.ERROR].includes(s.severity));
highPriorityStatuses.forEach(status => {
print(`High priority status: ${status.severity} - ${status.message}`);
});
getBigInteger()
getBigInteger(
entity):Uint8Array
Return a BigInteger typed value from a message field. Important!: Please note that this method returns a Java object "Big Integer" (a Java native data type). Because of this you cannot reliably use simple Javascript number operators without risking implicit conversion errors.
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
Uint8Array
Number in Java native BigInteger type.
Example
const n = message.getBigInteger(dataDictionary.type.Detail.CSV.A_REALLY_BIG_NUMBER_FIELD);
// Compare BigInteger to another BigInteger
const BigInteger = Java.type("java.math.BigInteger");
x = new BigInteger(123); // x now a java type BigInteger
x == 123; // -> "true", via implicit conversion --> be careful here, because x will be implicitly be converted to JS number and may lose precision
x.equals(123); // -> "false", because comparing different data types (BigInteger / Number)
x.equals(new BigInteger(123)); // -> "true"
getBoolean()
getBoolean(
entity):boolean
Retrieves a Boolean value from a specific field in the message's data dictionary.
This method accesses a boolean value from the message using the provided data dictionary entity.
Parameters
entity
The data dictionary entity that specifies the path to the boolean value in the message.
Returns
boolean
The boolean value from the specified field in the message.
Example
// Assuming we have a data dictionary entity for an "isActive" field
const isActiveEntity = dataDictionary.type.MyFormat.Detail.IS_ACTIVE;
// Get the boolean value, defaulting to false if not found
const isActive = message.getBoolean(isActiveEntity);
if (isActive) {
print("The item is active");
} else {
print("The item is not active");
}
getByte()
getByte(
entity):Byte
Return the Byte typed value from a message field. Important!: Please note that this method returns a Java object "Byte" (a Java native data type).
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
Java native Byte type.
Example
const b = message.getByte(dataDictionary.type.Detail.CSV.A_BYTE_FIELD);
getByteString()
getByteString(
entity):ByteString
Return the ByteString typed value from a message field. Important!: Please note that this method returns a "ByteString" typed value (a Java native data type).
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
ByteString type.
Example
const b = message.getByteString(dataDictionary.type.Detail.CSV.FIELD);
getCharacter()
getCharacter(
entity):Character
Return a Character typed value from a message field. Important!: Please note that this method returns a "char" typed value (a Java native data type).
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
Character in Java native char type.
Example
const c = message.getCharacter(dataDictionary.type.Detail.CSV.FIELD);
getCrc64()
getCrc64(
entity):string
Creates a CRC 64 checksum from specified node within a Message.
Parameters
entity
DataDictionaryEntity for which to create the CRC64 checksum.
Returns
string
CRC 64 checksum
Example
const crc64 = message.getCrc64(message.data.CSV);
getDate()
getDate(
entity):LocalDate
Return a LocalDate typed value from a message field. Important!: Please note that this method returns a "LocalDate" typed value (a Java native data type). LocalDate is a date without a time-zone in the ISO-8601 calendar system, such as "2022-12-03". This method is useful when you need to extract a date from a message field. If you need to extract a date-time with an offset from UTC/Greenwich, use the getDateTime method instead.
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
A date without a time-zone in the ISO-8601 calendar system, such as "2022-12-03".
Example
const dt = message.getDate(dataDictionary.type.Detail.CSV.A_DATE_FIELD);
getDateTime()
getDateTime(
entity):DateTime
Return a DateTime typed value from a message field.
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
A date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system, such as "2022-12-03T10:15:30+01:00".
Example
const dt = message.getDateTime(dataDictionary.type.Detail.CSV.FIELD);
getDecimal()
getDecimal(
entity):BigDecimal
Return a BigDecimal typed value from a message field. Important!: Please note that this method returns a "BigDecimal" typed value (a Java native data type).
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
BigDecimal in Java native char type.
Example
const dec = message.getDecimal(dataDictionary.type.Detail.CSV.FIELD);
getDouble()
getDouble(
entity):Double
Return a Double typed value from a message field. Important!: Please note that this method returns a "Double" typed value (a Java native data type).
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
Double in Java native char type.
Example
const dbl = message.getDouble(dataDictionary.type.Detail.CSV.FIELD);
getInt()
getInt(
entity):Integer
Return a Int typed value from a message field. Important!: Please note that this method returns a "Integer" typed value (a Java native data type).
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
Integer in Java native char type.
Example
const int = message.getInt(dataDictionary.type.Detail.CSV.FIELD);
getLong()
getLong(
entity):Long
Return a Long typed value from a message field. Important!: Please note that this method returns a "Long" typed value (a Java native data type).
Parameters
entity
DataDictionaryEntity describing the access path to the field value.
Returns
Long in Java native char type.