nats-io / nats-jms-bridge

NATS to JMS Bridge for request/reply
12 stars 3 forks source link

Bridge request/reply pattern, response on different subject #219

Open RichardHightower opened 4 years ago

RichardHightower commented 4 years ago

Hello Rick,

We were running request/reply use case where-in flow is like NATS-BRIDGE-MQ-BRIDGE-NATS. Nats client is publishing messages on subject showcase.helloworld.test which are mapped to queue DEV.QUEUE.1 and IBM MQ client is responding back on DEV.QUEUE.2 as per the below configuration. As of now, we get a response back on the same subject that is showcase.helloworld.test. So the question is can we have a response on different nats subjects instead of the original one? We tried adding response subject property under the config file but seems that it doesn’t work. In this case, it throws below error. Could you please advise?

NOT EXPECTING A REPLY NATS MESSAGE BUS NO REPLY TO CONVERT MESSAGE NATS TO BRIDGE::: creatornats::: DEFAULT HANDLER CALLED nats

CALLER INFO----

java.lang.Exception

        at io.nats.bridge.messages.MessageBuilder.withNoReplyHandler(MessageBuilder.java:92)

        at io.nats.bridge.nats.NatsMessageBus.convertMessage(NatsMessageBus.java:186)

        at io.nats.bridge.nats.NatsMessageBus.lambda$doReceive$0(NatsMessageBus.java:161)

        at io.nats.bridge.util.ExceptionHandler.tryReturnOrRethrow(ExceptionHandler.java:46)

        at io.nats.bridge.nats.NatsMessageBus.doReceive(NatsMessageBus.java:157)

        at io.nats.bridge.nats.NatsMessageBus.receive(NatsMessageBus.java:148)

        at io.nats.bridge.support.MessageBridgeImpl.process(MessageBridgeImpl.java:296)

        at io.nats.bridge.task.BridgeTaskRunner.process(BridgeTaskRunner.java:42)

        at io.nats.bridge.task.MessageBridgeTasksManagerImpl.lambda$start$0(MessageBridgeTasksManagerImpl.java:74)

        at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)

        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)

        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)

        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)

        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

java.lang.Exception

        at io.nats.bridge.messages.MessageBuilder.lambda$withNoReplyHandler$1(MessageBuilder.java:98)

        at io.nats.bridge.messages.BaseMessage.reply(BaseMessage.java:30)

        at io.nats.bridge.messages.BaseMessage.reply(BaseMessage.java:30)

        at io.nats.bridge.support.MessageBridgeImpl$MessageBridgeRequestReply.respond(MessageBridgeImpl.java:346)

        at io.nats.bridge.support.MessageBridgeImpl.processReplies(MessageBridgeImpl.java:314)

        at io.nats.bridge.support.MessageBridgeImpl.doProcess(MessageBridgeImpl.java:218)

        at io.nats.bridge.support.MessageBridgeImpl.process(MessageBridgeImpl.java:304)

        at io.nats.bridge.task.BridgeTaskRunner.process(BridgeTaskRunner.java:42)

        at io.nats.bridge.task.MessageBridgeTasksManagerImpl.lambda$start$0(MessageBridgeTasksManagerImpl.java:74)

        at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)

        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)

        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)

        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)

        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
bridges:

  - name: "natsToIBMMq"

    bridgeType: "REQUEST_REPLY"

    transforms: ["natstomqeventtransformexample"]

    replyTransforms: ["mqtonatseventtransformexample"]

    source:

      name: "nats"

      busType: "NATS"

      subject: "showcase.helloworld.test"

      responseSubject: "showcase.helloworld.simple"

      clusterName: "natsCluster"

    destination:

      name: "ibmMQ"

      busType: "JMS"

      subject: "DEV.QUEUE.1"

      responseSubject: "DEV.QUEUE.2"

      clusterName: "ibmMqCluster"

    copyHeaders: false

    workers: 1

    tasks : 1
RichardHightower commented 4 years ago

We added responseSubject because there was a requirement not want to use JMS temp queues (aka IBM dynamic queues) which is the preferred pattern for JMS and IBM MQ for request/reply. (This way you can scale out without pre-creating a ton of response queues ahead of time). We did not add this to NATS as it was never requested before nor deemed needed for idiomatic NATS usage. This request would mean that we need a version of the bridge that uses the methods publish and subscribe. Currently, the NATS bridge message bus (message bus.. a bridge is two messages busses that are bridge) uses the request method of the NATS client and the reply mailbox is a temp mailbox (aka subject, but called mailbox by Java NATS client internally but essential the reply subject). This is the preferred NATS usage. If you want the ability to create the responseSubject ahead of time, then we can schedule that work in. Colin is your point of contact for new work or features. It will take a day or so two to implement and another day or two to test out (give or take 50%).

This use case could be a straight pub/sub, not request-reply instead. Colin pointed that out as a workaround. This sounds like a feature request.

gstaware commented 4 years ago

We are discussing internally on this and get back to you with further updates.