Replaying from the Replay Log in the PubSub+ JCSMP API

This section describes how a client application using the PubSub+ JCSMP API should handle an event broker initiated message replay, and how a client application may initiate a message replay entirely on its own behalf.

If you're not familiar with message replay, take a look at Message Replay for a high-level introduction, and for detailed information on how to configure and use the feature on the event broker have a look at Message Replay Configuration.

There is also a Solace JCSMP tutorial that shows you how a client can initiate and process a replay.

Event Broker Initiated Replay

Client Initiated Replay

A client can initiate message replay for a variety of reasons including that it may be able to detect that it needs to replay messages from the replay log, or there may be a start-up condition in the client that requires that messages are replayed from a certain point-in-time.

Message replay may be initiated by a client whenever it binds to a queue or topic endpoint. You may want to consult the PubSub+ Messaging API for JCSMP reference for specific details on how to bind to a queue or topic endpoint. When creating a guaranteed message receiver, either flow or consumer, the application may specify a replay start location, to indicate the starting point of the message replay.

The different types of replay starting points supported are:

  • Replay from the beginning of the replay log.

  • Replay all messages starting from a specified timestamp.

  • Replay all messages after a specified replication group message ID.

To set the replay start location of a flow, use the ConsumerFlowProperties.setReplayStartLocation(...) method. The following code snippet shows a simple example:

if (dateStr != null) {
    Date date = simpleDateFormat.parse(dateStr);
    loc = JCSMPFactory.onlyInstance().createReplayStartLocationDate(date);
} else {
    loc = JCSMPFactory.onlyInstance().createReplayStartLocationBeginning();
}

consumerProps.setReplayStartLocation(loc);

For more information on how to specify these different replay starting points, see the PubSub+ Messaging API for JCSMP reference.

You should keep in mind that replay attempts from a timestamp earlier than when the replay log was created will fail. When the flow is successfully bound, it will receive all messages from the replay log starting from the specified replay start location.

Restrictions on client initiated replays

  • Not supported on non-exclusive endpoints.
  • Can't be initiated from a non-active flow.
  • Can't be initiated on a browser flow.
  • Can't be done using the JMS API.

If your application wishes to replay messages for a certain topic to a queue

When connecting to a topic-endpoint, the topic to be replayed from the replay log is set in the flow properties when the flow is created. If connecting to a queue, the messages published to the queue, that match subscriptions that exist on the queue prior to creating a flow, will be replayed. If the application wishes to replay messages for a certain topic to a queue, it must be sure to add a subscription to the queue before connecting the flow.

Replay failure

If a message replay fails, the event broker closes the client's flow, and notifies the application with a flow down event. The following code snippet shows a sample implementation of FlowEvent.FLOW_DOWN and the different subcodes that your application can receive:

public void handleEvent(Object source, FlowEventArgs event) {
    System.out.println("Flow " + flowName + " (" + source + ") received flow event: " + event);

    if (event.getEvent() == FlowEvent.FLOW_DOWN) {
        if (event.getException() instanceof JCSMPErrorResponseException) {
            JCSMPErrorResponseException ex = (JCSMPErrorResponseException) event.getException();
            
            switch (ex.getSubcodeEx()) {
                case JCSMPErrorResponseSubcodeEx.REPLAY_STARTED:
                case JCSMPErrorResponseSubcodeEx.REPLAY_FAILED:
                case JCSMPErrorResponseSubcodeEx.REPLAY_CANCELLED:
                case JCSMPErrorResponseSubcodeEx.REPLAY_LOG_MODIFIED:
                case JCSMPErrorResponseSubcodeEx.REPLAY_START_TIME_NOT_AVAILABLE:
                case JCSMPErrorResponseSubcodeEx.REPLAY_MESSAGE_UNAVAILABLE:
                case JCSMPErrorResponseSubcodeEx.REPLAYED_MESSAGE_REJECTED:
                case JCSMPErrorResponseSubcodeEx.REPLAY_START_MESSAGE_UNAVAILABLE:
                    break;
                default:
                    break;
            }
        }
    }
}

For more information on the different subcodes that could be received, see the PubSub+ Messaging API for JCSMP reference.