Considerations When Developing Applications That Use Oracle Messaging Cloud Service

Oracle Messaging Cloud Service is largely based on the Java Message Service (JMS) programming model.

Topics:

Oracle Messaging Cloud Service provides the same messaging patterns as JMS and also introduces a new pattern of its own. If you have experience with JMS, the concepts should be familiar. If you are not yet familiar with JMS, see About Messaging Concepts to review basic concepts such as destinations, producers and consumers, and connections and sessions.

The concepts in this section apply to both the REST API and Java library. Regardless of your experience with JMS or REST APIs, and whether you are developing applications with the Java library or REST API, it is important that you review the general guidelines documented in this section first, before referring to the subsequent sections for specific guidelines on Using the Java Library or Using the REST API.

About Queues and Topics

Queues and topics are types of destination to which messages can be sent.

  • Queues: Messages sent to a queue are received by one and only one consumer.

    When a message is sent to a queue, the message is kept until it is either received or until it expires. This quality of queues removes the timing dependency between producers and consumers, which means producers and consumers don't have to be available and communicating at the same time.

    When a message is received, the consumer can either automatically or manually acknowledge message receipt to the messaging platform, indicating whether the message was received or not. See About Sessions, Acknowledgement Modes, Transactions, and Provisional Messages for information about acknowledgement modes.

    Each instance of Oracle Messaging Cloud Service has a bound on the number of queues it can have. See About Resource Limits for the maximum number of messaging resources per service instance in paid and trial service subscriptions.

  • Topics: Messages sent to a topic may be received by multiple consumers or none.

    Consumers must be connected to a topic when a message is sent to the topic in order to receive the message. This quality of topics implies there is a timing dependency between message producers and message consumers. If a client has no consumers on a topic, it will miss any messages sent to the topic until it creates a consumer on the topic.

    If the timing dependency for receiving a message is undesirable, a client can create a durable subscription for the topic. A durable subscription stores all messages sent to a topic until each message is received.

    Each instance of Oracle Messaging Cloud Service has a bound on the number of topics and durable subscriptions it can have. See About Resource Limits for the maximum number of messaging resources per service instance in paid and trial service subscriptions.

The time-to-live or maximum time a message can live in Oracle Messaging Cloud Service is 14 days. The time-to-live can be set to a value less than 14 days for any given message. When a message reaches the defined time-to-live value, it is permanently deleted.

About Message Push and Message Push Listeners

Messages sent to a destination can be pushed to either another destination or to a user-defined URL through message push listeners.

A user-defined URL's scheme can be either HTTP or HTTPS. For message push to an HTTPS URL to succeed, the server to which messages are pushed must have a valid Secure Sockets Layer (SSL) certification from Verisign. A message push listener asynchronously receives messages from a queue, topic, or durable subscription. When a message is received by a message push listener, the message is pushed to the configured target.

Messages can only be pushed to a user-defined URL via PUT and POST HTTP requests.

Message push listeners can have specific retry and failover policies that define what the message push listener does if delivery of a message to a target fails. Failover policies can push a message to another destination or user-defined URL. If a message push listener cannot deliver a message and no failover policy is specified, then the message push listener discards the message.

Message push listeners will not follow HTTP redirects. If a message push listener makes an HTTP request to push a message to a user-defined URL, and receives a redirect response (that is, a response whose status is in the range 300-399), the message push listener will treat it as an error response. Any further handling of the message will be as defined by the message push listener's failover policy. The message push listener will not push the message to the location specified in the redirect response.

Each instance of Oracle Messaging Cloud Service cannot be assumed to support more message push listeners than available connections (which are required to send and receive messages). See About Connections for information about why it is important to assume that each message push listener will use a dedicated connection.

About Verification of Message Push Listeners

A message can be pushed to a user-defined URL using a message push listener. Before a message push listener can be created, Oracle Messaging Cloud Service must verify all URL targets of the message push listener. In other words, a message push listener is created only after the service has verified that all URLs to which the listener might push a message are willing to receive such pushes, as shown in the following diagram.

The process to verify the URL targets of a message push listener is as follows:

  1. A request is made to create a new message push listener, through either the REST API or Java library. Note that the message push listener is not actually created until its URL targets have been verified.

  2. Oracle Messaging Cloud Service sends a verification request to every user-defined URL in the listener's definition (primary target and failover targets). Each verification request is an HTTP request that includes the following:

    • An HTTP header with name X-OC-MPL-CHALLENGE whose value is a service-generated pseudorandom challenge token

    • An HTTP header with name X-OC-MPL-VERIFICATION whose value is a user-provided verification token

  3. For a verification request to succeed, the user-defined URL must echo the pseudorandom challenge token as the body of the HTTP response, and the HTTP response must return with a status code of 200. Optionally, the user-defined URL can also validate the value of the user-provided verification token. If the verification request receives a redirect response, the verification request fails.

    The verification token is essentially a way for a client creating a message push listener to identify itself to the endpoint as a trusted entity. The verification token could, for example, be a secret string shared between the endpoint and the client, a one-time password, or a cryptographically signed token. The client and endpoint are free to use the value in whatever way they like.

  4. If the verification request fails for any user-defined URL, the creation of the message push listener will also fail.

    The purpose of verifying each user-defined URL is to ensure that the owner of the URL is willing to accept pushed messages.

About Destination Deletion

This section provides information about what happens when a client is using, or attempts to use, a non-temporary destination (queue or topic) that is deleted.

Deleting a non-temporary destination is a non-blocking operation. The operation of deleting a destination (either through the REST API or through the Java library) can complete and return control to the client, and the destination can still be in the process of being deleted. Destinations that are in the process of being deleted, but whose deletion is not yet complete, are referred to as being marked for deletion. Destinations that are marked for deletion will still be listed when all destinations are listed, and their properties can still be retrieved. They will, however, have status MARK_FOR_DELETION. A destination can have status MARK_FOR_DELETION for some time.

Any use of a destination that is marked for deletion may fail. This includes sending to it, receiving from it, browsing it (if it is a queue), creating message push listeners on it, having a message push listener push messages from it or to it, etc. This applies both to attempts to use the destination after it is marked for deletion and uses of the destination that began before it was marked for deletion. Sends to a destination that is marked for deletion may succeed or fail. Messages on or sent to a destination that is marked for deletion may or may not be lost. It is recommended that applications be implemented so as to avoid making any use of destinations that are marked for deletion, for example, by using a fixed set of destinations that does not change over time, shutting down all uses of a destination before deleting it, etc.

Message push listeners that listen on a destination that becomes marked for deletion will be deleted automatically. Applications that might be sensitive to the exact time that a message push listener is deleted after its destination is marked for deletion should delete the message push listeners on a destination manually before deleting the destination.

Message push listeners that push to a destination that is marked for deletion or fully deleted will not be deleted automatically when that destination is deleted. Any message push listener that pushes to a destination that might be deleted while the message push listener still exists should be configured with a failure policy that ensures that messages will not be lost if the target destination is deleted.

About Connections

Connections are required to send and receive messages between clients and Oracle Messaging Cloud Service. A connection represents all of the resources needed for communication between clients and the messaging platform.

A client usually uses one connection for all of its sending and receiving operations, though a client can use multiple connections if desired.

Each instance of Oracle Messaging Cloud Service has a quota of concurrent connections. When an instance is using 100% of the connection quota, additional attempts to establish new connections will fail.

A new connection is used when:

  • A connection is created through the REST API

  • A JMS connection is created through the Java library

  • A message push listener is created

Oracle Messaging Cloud Service may allocate message push listeners to connections in different ways in order to optimize performance. The service may have multiple message push listeners use the same connection or have different message push listeners use different connections.

See Messaging Context and HTTP Cookies and Cross-Site Request Forgery (CSRF) Prevention for additional guidelines when using the REST API.

About Sessions, Acknowledgement Modes, Transactions, and Provisional Messages

Once a connection has been created, a session must also be created before messages can be sent or received. A session provides a behavioral context that defines what it means for messages to be sent and received between clients and Oracle Messaging Cloud Service.

A single connection can have multiple sessions. Unless explicitly closed, sessions persist until the connection from which they are created is closed.

A message received by a client through a session must be acknowledged before its receipt is treated as final by Oracle Messaging Cloud Service. When a session is created, its acknowledgement mode must be set to one of the following options:

  • Auto-acknowledge: In auto-acknowledge mode, every message received is automatically acknowledged immediately after it is received. Any message received through an auto-acknowledge session is final.

  • Client-acknowledge: In client-acknowledge mode, clients must explicitly acknowledge all message receipts. This allows clients to examine a message to determine if it is prepared to consume the message or not. It is recommended that this mode be used if the session is not transacted and if the Messaging Service is being used for applications in which messages must not be lost.

  • Duplicates-OK: In duplicates-OK mode, message receipts are acknowledged automatically, but lazily, which means messages are not individually acknowledged when they are received but are automatically acknowledged at a later point in time. This mode reduces the communication overhead between clients and the messaging platform, and may increase the rate at which messages are received.

    Using the duplicates-OK mode, however, may result in any given message being delivered multiple times, potentially to more than one client. If a session using this acknowledgement mode unexpectedly closes, the messages delivered to the client since the last acknowledgement may be made available for delivery to other clients.

Sessions created through the REST API are auto-acknowledged by default. Sessions created through the Java library must have their acknowledgement mode specified explicitly.

Instead of specifying an acknowledgement mode, a session can be configured such that sequences of send and receive operations are grouped into atomic operations known as transactions. Like acknowledgement modes, sessions are configured to be transacted or not transacted when the session is created. In a transaction, all grouped send and receive operations either complete or do not complete collectively.

At any point in a transaction, the client can call rollback, and all previous send and receive operations within that transaction will be cancelled. Transacted sessions must be explicitly committed. When the client calls commit on a transaction, all send and receive operations are made permanent and a new transaction is started.

In sessions whose mode is client-acknowledge, the client receiving messages is responsible for explicitly acknowledging that messages have been received. Until the client explicitly acknowledges a message, received messages are considered to be provisional. If the client fails to perform acknowledgement, provisionally received messages are returned to the destination and made available to be received by another client when the session or its connection is closed.

Similarly, in transacted sessions the client sending and receiving messages is responsible for explicitly committing the session. Until the session is committed, all sent and received messages within the transaction are considered to be provisional. Failure to commit transacted sessions will cause provisionally sent messages to be discarded and provisionally received messages to be made available for delivery to other clients. In both client-acknowledge mode and transacted sessions, when a provisionally received message becomes available to be delivered to another client, and when the message is so delivered, it is marked as redelivered.

About Producers, Consumers, and Selectors

A session sends messages through a producer and receives messages through a consumer. A session can have multiple producers and multiple consumers. Unless explicitly closed, producers and consumers persist until the session in which they are created is closed.

A producer defines the default characteristics of how messages are sent to and stored within the messaging platform. A producer can specify the destination to which all messages are sent, how sent messages should be stored on the target destination, and how long sent messages can live in the service before they expire.

A consumer defines how messages are received from the messaging platform. A consumer must specify the destination from which messages are received.

Optionally, consumers can select a subset of all available messages to be received from a destination by specifying a selector. A selector is an SQL-like expression that specifies a condition that a message must satisfy to be eligible for the consumer to receive the message. Selectors can only select messages based on criteria in the message headers and properties. Selectors cannot select messages based on the contents or type of a message body (for example, Text or Object type). For the syntax of selectors, see the Message Selectors section of the Java API reference for the javax.jms.Message class. For the syntax of selectors, see the Message Selectors section of the Java API reference for the javax.jms.Message class at the URL:

http://docs.oracle.com/javaee/6/api/javax/jms/Message.html

About Parts of a Message

Messages are unique, discrete units of information that pass between two or more clients through Oracle Messaging Cloud Service. Each message has three parts: headers, properties, and a body.

Topics:

Message Headers

Message Properties

Message Body and Message Size

Message Headers

Message headers are predefined key/value pairs associated with a message.

Message headers are used by the messaging platform for message identification and routing purposes. Some headers are client-set and some are broker-set. For client-set headers, ‘Required’ means that the client must supply the header and ‘Optional’ means that client need not supply it. For broker-set headers, ‘Required’ means the broker will always set it, whereas ‘Optional’ means the broker may or may not set it.

The headers, some of which may or may not be present in a message, are:

  • Correlation ID: An identifier that can be set by the sending client to correlate multiple messages. The value of this header is set by the sending client.

  • Delivery Mode: Required. The persistence type of the message. The value of this header is set by the sending client.

  • Destination: Required. The destination to which the message was sent. The value of this header is set by the sending client. For more information, see About Persistent and Non-Persistent Messages.

  • Expiration: Required. The time when the message will expire. The value of this header is a long integer, and is interpreted as Unix time. This value is set by the JMS broker, but is partially a function of the message's time-to-live, which is set by the sending client.

  • Message ID: Required. The globally unique ID of the message. This value is set by the JMS broker.

  • Redelivered: Required. Indicates whether the message has been delivered at least once before. Value is true or false. This value is set by the JMS broker.

  • ReplyTo: A destination to which replies to this message should be sent. Controlled by the sending client.

  • Time: The time when the message was sent to the destination. Set by the JMS broker.

Message Properties

Message properties are optional key/value pairs associated with a message. Some message properties are user-defined, and some are set by the system.

Message property values can have the following classes:
  • Boolean

  • Byte

  • Short

  • Integer

  • Long

  • Float

  • Double

  • String

Selectors can use message properties to restrict the messages received by a consumer. See About Producers, Consumers, and Selectors for information about selectors.

Message Body and Message Size

A message body must have a type, which defines the format and structure of the body.

The message type can be one of the following:

  • PLAIN: The message has no body. It only has headers and properties.

  • TEXT: The message body is a String.

  • BYTES: The message body is an array of bytes.

  • OBJECT: The message body is a serialized Java object.

  • MAP: The message body is a set of key/value pairs. Keys are Strings and values are Java objects. Each value can be either a Boolean, Byte, Character, Short, Integer, Long, Float, Double, String, or an array of bytes.

  • STREAM: The message body is a stream of Java objects. Each object in a stream is either a Boolean, Byte, Character, Short, Integer, Long, Float, Double, String, or an array of bytes.

  • HTTP: The message body is a serialized Java object that contains a byte array representing the body of an HTTP request or response, and Strings representing the HTTP headers that specify the language and media type of that body.

Messages have a maximum size of 512KB. Send operations with messages larger than 512KB will fail. See Accessing Oracle Messaging Cloud Service Using REST API and Accessing Oracle Messaging Cloud Service Using Java Library for information about how message size is calculated.

About Persistent and Non-Persistent Messages

When a message is sent to a destination, the message delivery mode is marked as persistent by default.

Persistent messages are guaranteed to be stored in a durable medium while being processed by Oracle Messaging Cloud Service. This means persistent messages are not lost if Oracle Messaging Cloud Service temporarily goes down.

Optionally, messages can be marked as non-persistent. Non-persistent messages may or may not be stored in a durable medium. Since non-persistent messages do not require as much I/O as persistent messages, higher throughput rates may be achieved by using non-persistent messages. If Oracle Messaging Cloud Service temporarily goes down, however, non-persistent messages may be lost.

A queue or topic cannot have more than 100,000 messages at any given time. Send operations to a destination with 100,000 messages will fail. The 100,000 limit applies to either persistent or non-persistent messages, or a combination of both.

Note:

While persistent messages are always stored in a durable medium, there are rare instances when the durable medium and the messages stored may be lost. Additional copies of mission-critical data should therefore always be stored in secure and reliable locations.

About Authorization

User roles and privileges are described in Getting Started with Oracle Cloud.

In addition to the roles and privileges described in Managing User Accounts and Managing User Roles in Getting Started with Oracle Cloud, two default account roles, Messaging Administrator and Messaging Worker, are created for Oracle Messaging Cloud Service when the service instance is provisioned. Each role has privileges that define what operations users are authorized to perform in the service instance. Any user with the Messaging Administrator role can potentially delete any destination within the instance. Any user with the Messaging Administrator role or the Messaging Worker role can potentially send or receive messages to any destination within the instance. See About Oracle Messaging Cloud Service Roles and Users for additional privileges associated with each role.

About Service Termination

When an instance of Oracle Messaging Cloud Service is terminated, no customer data is archived. Messages residing on destinations are deleted immediately upon service termination.

Before terminating an instance, be sure to drain and store messages from queues and durable subscriptions if the contents of stored messages are important.

About the Ordering of Message Delivery

Oracle Messaging Cloud Service does not provide any strict guarantees about the order in which messages are delivered.

Applications for which message ordering is critical should use the "redelivered" message header to detect redeliveries, and should consider the use of timestamps or sequence numbers, possibly attached to messages as message properties or in the message bodies, to ensure that messages are processed in the proper order.

Using Message Groups

Message groups can be used to send a message that is larger than 512KB in a set of multiple smaller messages using a queue.

Message groups are used to group different messages that should all be processed by the same consumer. Message groups are created implicitly by sending messages that have a message ID and sequence number set on them to a queue.

A message group is defined by a group ID and a group sequence number. If a message belongs to a group, the group it belongs to is defined by the value of its JMSXGroupID property.

Note:

  • If you send messages in a specific group to a queue, and the sequence numbers are out of order, the consumer will receive them in the order in which they were sent, not in order of message sequence.

  • The first message sent in a group must have sequence number 1.

  • Sequence numbers have no effect on message receipt order from queues.

  • Sequence numbers are not used to eliminate duplicate messages.

  • The use of message groups has no effect when used with topics: all consumers on the topic will get all messages, and receipt order will not be affected by sequence numbers.

  • Sequence numbers play an important role in the delivery of messages in a message group. For example, consider a scenario such as the following:
    • Messages are sent in group G. Consumer C is chosen to receive group G, and gets some of the messages.

    • After consumer C receives few messages from group G, consumer C is closed. However, more messages are sent in group G.

    • A new consumer, D, is chosen to receive messages in G.

    • When consumer D receives messages that don’t start with sequence number 1, D can conclude that some other messages in the group were sent to some other consumer.

Method: POST

Path: /producers/producerName/messages

Scope: Messaging Context

Authorization: Messaging Administrator or Messaging Worker

Request Parameters:

Parameter Description

groupId

This parameter is used to set the JMSXGroupID property on the message being sent. This is the name of the message group of which this message is a part, if any.

Note:

If the JMSXGroupID property is set as an HTTP request header, it must be set to an escaped value String or a badParameter error response will be generated. For more information on escaped value Strings, see About Escaped Value Strings. If the JMSXGroupID property is set as a query string parameter, the usual conventions for escaping query string parameters hold.

groupSeq

This parameter is used to set the JMSXGroupSeq property on the message being sent. This is the sequence number of the message within the message group specified by the groupId parameter. The groupSeq parameter must be set to an integer or a badParameter error response will be generated.

Result: Sends multiple messages as a message group using a queue.

Error Responses:

Error Message Description

badParameter

The groupSeq parameter was not set to an integer.

incompleteGroupProperties

Exactly one of the JMSXGroupID and JMSXGroupSeq properties was set on the message. Either both properties must be set, or neither must be set.

See Use Message Groups for a code sample on sending messages using message groups.