Creating Messages in the PubSub+ JCSMP API

Messages are explicitly created by client applications when publishing and are implicitly created by the PubSub+ JCSMP API on matching message delivery. The PubSub+ JCSMP API creates an object of the specified class (see Java Message Classes below) to encapsulate a message.

When creating messages, the following factors should be considered:

Message Ownership

When creating messages for publishing, there are two message ownership models:

  • Session-independent

    In a session‑independent message ownership model, client applications can reuse messages between send operations. Messages are allocated on demand and are disposed explicitly by client applications when they are done with the messages.

  • Session-dependent

    JCSMP also supports a session-dependent message ownership model. In this model, message instances are pre-allocated into a producer message pool; client applications can ‘take’ a message instance from the message pool, populate it, and send it. When the send operation returns, the message instance is automatically reset and ‘put’ back into the message pool by the API. This is done through the Producer interface on the session. Session‑dependent messages cannot be used in a batch send.

    The session-dependent message ownership model is primarily maintained for backwards compatibility with existing applications that use JCSMP. It is recommended that new Java applications use the session‑independent messages. There is no performance penalty for using the session‑independent message ownership model if messages are pre‑allocated and reused, whenever possible.

To create session-independent Messages, use JCSMPFactory.createMessage(...). This method creates an object of the specified class to encapsulate a message.

For an example of how to create session‑independent messages, see the ADPubAck sample on the Solace Developer Hub.

To Create session-dependent messages, use the following methods:

  • producer.createBytesXMLMessage()
  • producer.createBytesMessage()
  • producer.createMapMessage()
  • producer.createStreamMessage()
  • producer.createTextMessage()
  • producer.createXMLContentMessage()

Message Types

The PubSub+ messaging APIs support different message types as defined by the message payloads. For programmers’ convenience, the following type‑safe message types/classes are provided in the PubSub+ JCSMP API.

JCSMP Message Classes

Message Class Description

BytesXMLMessage

An unstructured class that can be used to send a message containing an XML data payload.

BytesMessage

A structured class that can be used to send a message that contains a stream of uninterpreted bytes in a binary attachment.

MapMessage

A structured class that can be used to send a message that contains a structured data type (SDT) map. Refer to Using Structured Data in the PubSub+ JCSMP API.

StreamMessage

A structured class that can be used to send a message that contains a SDT stream. Refer to Using Structured Data in the PubSub+ JCSMP API.

TextMessage

A structured class that can be used to send a message that contains text.

XMLContentMessage

A structured class that can be used to send a message that contains XML data.

Resetting Messages

When reusing a message in the Session-independent message ownership model, you can release all memory associated with a message buffer so that the message buffer is reset to its original state (that is, as if it has just been allocated). All fields are reset to their default values.

To reset a message, use XMLMessage.reset().

Setting Message Properties

A number of important message properties can be set for Guaranteed messages, which will affect how messages are routed when they are published.

For a complete list of message properties that can be set, refer to the PubSub+ Messaging APIs documentation for the appropriate messaging API.

Ack Immediately

If this property is set to false (the default), the event broker should send an acknowledgment for the messages received in the publish window when a threshold of either a third of the Publish Window Size is reached or one second has elapsed. These are non-configurable thresholds on the event broker.

  • This property has no effect on an outgoing Direct message or on a message received by a client.
  • This property may or may not be removed by the receiving event broker prior to its delivery to a receiving client. Therefore, receiving clients should not rely on this property being present.

To set whether the event broker should acknowledge published messages immediately, use Message.setAckImmediately(...).

Class-of-Service

A COS level of 2 is a reserved Solace value; currently a message with a COS level of 2 is treated as low priority.

You must set the COS value using the data structure provided by each API. Do not set the value directly using an integer.

For information on how to configuring a queue or a topic endpoint to be able to selectively discard low-priority messages, refer to the reject-low-priority-msg and reject-low-priority-msg-limit Queue CONFIG and Topic Endpoint CONFIG commands in Guaranteed Messaging Configuration.

To set a COS flag, use Message.setCos(...).

Correlation ID

A unique correlation ID (in the form of a string) can be set for a message. A correlation ID can be used to correlate a request message and its corresponding reply. A correlation ID can also be used as an identifier in a message selector.

For information on using Request Reply messaging for Guaranteed messages, refer to Request Reply Messaging in the PubSub+ JCSMP API. For information on selectors, refer to Using Selectors in the PubSub+ JCSMP API.

To set a correlation ID, use Message.setCorrelationID(...).

Dead Message Queue Eligibility

Guaranteed messages that have exceeded their TTL or maximum number of redelivery attempts can be moved from a durable Queue or a Topic Endpoint to a DMQ, instead of being discarded if those messages are flagged as being DMQ-eligible. A DMQ is just a durable queue that has been assigned to serve as the DMQ for another durable endpoint. For more information, refer to Configuring Dead Message Queues

DMQ eligibility is a set as a message flag. A value of true enables a published message to be DMQ-eligible.

Setting DMQ eligibility for a Direct message only has an effect when the message's Topic matches a Topic subscription on an endpoint and the event broker changes the received message's delivery mode to Non-Persistent. For more information on how received messages' delivery modes can be modified for Topic matching, refer to Guaranteed Messages.

To enable message eligibility for DMQs, use Message.setDMQEligible(...).

For an example of how to make messages DMQ-eligible, refer to the messageTTLAndDeadMessageQueue sample on the Solace Developer Hub.

Deliver-To-One Subscribers

The Deliver-To-One property can set for Guaranteed Messages when they are published.

The Deliver-To-One flag only affects the delivery of messages with a Direct delivery mode. Therefore, when the Deliver-To-One flag is enabled for a persistent or non-persistent message, it does not affect message delivery behavior, unless the delivery mode of that message is changed to Direct when it matches a Topic subscription assigned to a queue or topic endpoint destination. In this case, the message that is changed to Direct is only be delivered to a single Direct message consumer, rather than all, even though there might be a number of clients with appropriate subscriptions that are capable of receiving the message.

To set a deliver-to-one message flag, use XMLMessage.setDeliverToOne(...).

Delivery Mode

Each published message has a delivery mode. Direct delivery is the default. To use Guaranteed Messaging, set the delivery mode to persistent in most cases.

A Non-Persistent delivery mode is also available for Guaranteed Messaging; however this mode is supported only for JMS messaging.applications.

For more information, see Message Delivery Modes in the PubSub+ JCSMP API.

To set a delivery mode, use Message.setDeliveryMode(...).

For an example of how to set the delivery mode for a message, refer to the DirectPubSub sample on the Solace Developer Hub.

Destination

A published Guaranteed message is routed according to its set queue or topic destination. A destination is set on the send method used to publish the message. Refer to Sending One Message at a Time or Sending Multiple Messages at Once.

Related Samples

For an example of how to publish a message to a topic, refer to the DirectPubSub sample on the Solace Developer Hub.

For an example of how to publish a message to a queue, refer to the QueueProvisionAndBrowse sample on the Solace Developer Hub.

Message Eliding Eligibility

The message eliding capabilities of the event broker enables clients to only receive the most current Direct messages published to Topics that they subscribe to, at a rate that they can manage. Using message eliding can be useful in situations where a slower message rate is required or there are slow subscribers (that is, clients that are not consuming messages quickly enough).

To use message eliding, the following are required:

  • Published messages must be flagged as eligible for message eliding.
  • A receiving client application must be assigned a client profile through its client username that permits it to use message eliding. The client profile also sets a rate to control the delay interval at which a new eliding-eligible message elides a previous version that is queued for delivery to the client. For information on how to configure client profiles and assign them to clients, refer to Configuring Client Authentication.

The message eliding flag only affects the delivery of messages with a Direct delivery mode. Therefore, when the message eliding flag is enabled for a persistent or non-persistent message, it does not affect message delivery behavior, unless the delivery mode of that message is changed to Direct when it matches a client topic subscription. In this case, the message that is changed to Direct can then be elided.

To enable message eligibility for eliding, use Message.setElidingEligible(...).

Message Expiration

You can set an expiration time (in milliseconds), from midnight, January 1, 1970 UTC, on a sent message. By default, a published message's expiration value is 0, which means that the message never expires.

The message expiration field is transported from end-to-end through the event broker only when a client explicitly sets an expiration value greater than 0, and TTL is not set or is set to 0.

To set message expiration, use Message.setExpiration(...).

To maintain an accurate message expiration value, it is important to synchronize the system clocks of the clients connecting to the event broker.

Message TTL is the only mechanism in the messaging network for preventing expired messages to be delivered to clients. Setting an expiration value has no effect on the life cycle of a message in the messaging network. That is, a message with an expiration time that has passed is still delivered to consumers. If it is determined that some further action (such as discarding the received message) should occur, it is the responsibility of a receiving application to perform that action.

Enabling Message Expiration Calculation

To calculate a message expiration value that also accounts for a message TTL value, enable message expiration calculation for the Session . By default, to improve system performance, message expiration calculation is not enabled.

When message expiration calculation is enabled, and the message has a TTL value greater than 0, the API updates the message's expiration value with the sum of the message TTL and the UTC value after the message is sent or received.

Setting TTL and expiration values for messages with Direct delivery modes only has an effect if the event broker automatically changes the messages' delivery mode from Direct to non-persistent because the messages' Topics match a Topic subscription assigned to an endpoint. For information on how messages' delivery modes could be changed to fulfill topic matches, refer to Topic Matching and Message Delivery Modes.

To enable message expiration calculation, use the JCSMPProperties.CALCULATE_MESSAGE_EXPIRATION property.

For an example of how to set an expiration time or enable message expiration calculation, see the messageTTLAndDeadMessageQueue sample on the Solace Developer Hub.

Message Priority

You can apply a message priority value to messages that are published to an event broker. When queues or topic endpoints are configured to respect message priority, the event broker uses this value to deliver the message in the appropriate order. In other words, messages with a higher priority are sent before messages with a lower priority. A value of 0 is the lowest priority, and a value of 255 is the highest priority (though the event broker treats all values higher than 9 as priority 9). The default value is 4.

When an endpoint is configured to enforce message priority, it increases the chance that duplicate messages will be delivered to a consuming client after it recovers from a connection failure.

To set message priority, use Message.setPriority(...).

Partition Key

You can set a partition key in your message to take advantage of partitioned queues. Partitioned queues allow you to easily scale the number of consumer applications in your event mesh, while maintaining the message sequence for all published messages with the same partition key. PubSub+ event brokers ensure that all related events are delivered to the same consumer in the correct sequence and also re-balance the event stream when you add or remove consumers. For more information see Partitioned Queues.

You set the partition key in the API by specifying the user message property listed in the table below. This value is stored in the JMSXGroupID field in the message and remains unchanged between network hops.

To configure the key in a PubSub+ message property to use partitioned queues, use the putString(key,value) function to set a key-value pair on a message, where:

  • key—The constant XMLMessage.MessageUserPropertyConstants.QUEUE_PARTITION_KEY or the string value of JMSXGroupID.

  • value—A string representing the value of your partition key. Client applications set the value at publish time.

The following example sets the partition key value to Group-0:

TextMessage message = JCSMPFactory.onlyInstance().createMessage(TextMessage.class);   
SDTMap messageProperties = JCSMPFactory.onlyInstance().createMap();
messageProperties.putString(XMLMessage.MessageUserPropertyConstants.QUEUE_PARTITION_KEY,"Group-0");
message.setProperties(messageProperties);

ReplyTo Destinations

When the message is to be published as a request, a ReplyTo destination can be set to indicate where the reply to the request message should be sent. For information on using Request Reply messaging for Guaranteed messages, refer to Request Reply Messaging in the PubSub+ JCSMP API.

To set a ReplyTo destination, use Message.setReplyTo(...).

For an example of how to create a Guaranteed request message, which includes a ReplyTo destination, refer to the RRGuaranteedRequester and RRGuaranteedReplier samples on the Solace Developer Hub.

Time-To-Live

To ensure that old messages are not delivered to consuming clients, you can set a Time-To-Live (TTL) in milliseconds for each Guaranteed message to be published. When queues or topic endpoints are configured to respect message TTLs, and a received message's TTL has passed, it can be discarded by the endpoint, or, if the message is eligible for a Dead Message Queue (DMQ), moved to a DMQ provisioned on the event broker.

By default, a published message's TTL value is 0, which means that the message never expires.

For information on how to configure an endpoint to respect message TTLs, refer to Defining Endpoint Properties in the PubSub+ JCSMP API or to the PubSub+ Messaging APIs documentation for the messaging API used. For information on making messages eligible for DMQs, refer Dead Message Queue Eligibility.

To set the Time-To-Live value on a message, use Message.setTimeToLive(...).

For an example of how to set a TTL for published messages, refer to the messageTTLAndDeadMessageQueue sample on the Solace Developer Hub.