How to send NACK(Negative Acknowledgement) using java API

Hi Team,

Need your help to find the solution.

Current Implementation details,

SolConnectionFactory connectionFactory = SolJmsUtility.createConnectionFactory(); --> for create connection factory
using host , vpn,trust store,keystore with auth scheme AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE

this.connection = connectionFactory.createConnection(); --> connection creation

session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); -> session creation using client acknowledge

Using MessageListener to listen the queue

public class MyListener implements MessageListener

public void onMessage(Message message)  -> receive the message and process
    {in this method validating the message(poison message ) and publish to kafka,
    once receive the success message from kafka acknowledge the message}
    message.acknowledge();

Problem : If kafka broker went down how to do retry ? we had a discussion with internal solace team.

Our Assumption:
If client is not calling the message.acknowledge(); -> solace will do the retry but internal solace team clarified that it is using windowing mechanism, so if subsequent message is acknowledge then previous message will also acknowledged and deleted.

Their suggestion is send back the NACK(negative acknowledgment) for failed message then solace can do retry that message.
How to send the NACK using Java API ?
What are the suggested value for Max_Un_Ack_Message and Max_Redeliver_Count?

Maven Dependency for Solace:

com.solacesystems
sol-jms
10.0.0

Tagged:

Comments

  • Ragnar
    Ragnar Member, Employee Posts: 64 Solace Employee

    Windowing, i.e, transport flow control, is unrelated to message.acknowledge(). Transport flow control is controlled by how fast you consume messages. If you do not call receive() on a synchronous consumer, or call stop() on an asynchronous consumer as in your cases, the transport window will close.

    message.acknowledge() on the other hand is only for acknowledging the message has been received and consumed. At this point the message is removed from the persistent storage on the Solace broker. If you do not call message.acknowledge() this does not stop delivery of subsequent messages until max-unacked-message limit is reached which is typically quite large.

    Unacknowledged messages are only redelivered on the next consumer to connect.

  • Karuppusamy
    Karuppusamy Member Posts: 3

    @Ragnar thanks a lot for your quick reply.

    Is there any concept negative acknowledge in solace?

    If so , is any Java API is available to achieve the same ?

  • Ragnar
    Ragnar Member, Employee Posts: 64 Solace Employee

    Currently, the Solace APIs and broker do not support negative acknowledgement from consumers. There are in-house groups studying this as a feature. Currently Solace is gathering information on what the outcome of a negative acknowledgement should mean.

  • Karuppusamy
    Karuppusamy Member Posts: 3

    @Ragnar, thanks for your input.

    I used connection.session.recover(); --> for downstream failure in my consumer.
    It keeps retry the message, Is it fine to use this method ?
    Any bottleneck to use this method?(run multiple instance in the production)

    The retry solace message don't have any property to claim this is retry message(retrycount, redeliveryattempt).

    Sample retry messages:(updated the topic for security)
    SolTextMessage={ JMSCorrelationID:6a3c9ed6-938e-4f50-9134-384e3266b6c3,JMSDeliveryMode:2,JMSDestination:Topic 'v1///json-v1/hk/req///',JMSExpiration:0,JMSMessageID:ID:10.141.127.40e1c217c304a56800:2,JMSPriority:0,JMSRedelivered,ReplyTo:Topic 'v1///json-v1/hk/req///',JMSTimestamp:1632899237166,JMSProperties:{conversationID:fe62613f-f653-45ef-9537-9e39fbcd0855,JMS_Solace_isXML:true,JMS_Solace_DeliverToOne:false,JMS_Solace_DeadMsgQueueEligible:false,JMS_Solace_ElidingEligible:false,Solace_JMS_Prop_IS_Reply_Message:false},SolPayload:{XML:len=1416} }

    SolTextMessage={ JMSCorrelationID:6a3c9ed6-938e-4f50-9134-384e3266b6c3,JMSDeliveryMode:2,JMSDestination:Topic 'v1///json-v1/hk/req///',JMSExpiration:0,JMSMessageID:ID:10.141.127.40e1c217c304a56800:2,JMSPriority:0,JMSRedelivered,ReplyTo:Topic 'v1///json-v1/hk/req///',JMSTimestamp:1632899237166,JMSProperties:{conversationID:fe62613f-f653-45ef-9537-9e39fbcd0855,JMS_Solace_isXML:true,JMS_Solace_DeliverToOne:false,JMS_Solace_DeadMsgQueueEligible:false,JMS_Solace_ElidingEligible:false,Solace_JMS_Prop_IS_Reply_Message:false},SolPayload:{text} }

  • Ragnar
    Ragnar Member, Employee Posts: 64 Solace Employee

    You only need to recover the single consumer that had the problem. If you recover() on the session it will recover() all consumers which is not necessary if you have multiple consumer instances.

    JMSRedelivered is set in the redelivered messages. You can also retrieve JMSXDeliveryCount which will be '1' on the first delivery and greater than 1 on all redelivered messages.