Binders

Introduction

Now lets start the advance understanding for the cndi, with the quick start guide we saw how to use Autowired annotations and initialize a global bean object. It this part we will take a look at binders and Message brokers.

The binders are actually used to bind a topic to a channel, so let's take an example of a Pub/Sub Message Broker, where we have a Publisher and a Subscriber. A publisher will publish a message to 'xyz' topic, a Subscriber will subscribe to 'xyz' topic and will receive any event data publish to that topic. This is how a messaging system work in a high level overview.

Now so let's say we have a message broker, a publisher and a subscriber that subscribe to a topic[s] in a normal architecture we create an instance for publisher and subscriber that connects to message broker and boom we have our messaging system app.

But take a scenario where we have to deal with multiple message broker servers, (i.e. mqtt, rabbit etc) we might need to manually take care of publishers/subscribers, to resolve this problem we add a layer in the pub/sub architecture and the layer is called Binder.

Message Binder and Message/Subscriber Channel

To use message binder we need a message channel, a message channel can a alphabetic string that binds a topic.

Syntax

rcn.binders.message.mqtt.<producer|consumer>.<channelName>.destination = <topic-name>

Implementation

To implement Binders in the Application we need to use MessageChannel/SubscriberChannel class, MessageChannel is for producer/publisher and SubscriberChannel is for consumer/subscriber. The default configuration properties that need to be added in the yaml configuration are below

rcn.binders.message.enable: Enables the DefaultMessageBinder
rcn.binders.message.default: The property which describes the message broker to use currently only mqtt is supported
rcn.binders.message.brokerUrl: ip address to broker
rcn.binders.message.brokerPort: port of the broker to connect

The yaml properties looks like:

rcn:
  binders:
    message:
      enable: true
      default: mqtt
      brokerUrl: localhost
      brokerPort: 1883
Create Producer/Publisher

Let's create Producer using message binder, using @Output decoration we can create a MessageChannel instance that automatically configures a channel to the topic. The only thing to produce a message is to call send method from MessageChannel

@Component
class Source:
    outputChannel1Binding: MessageChannel
    @Output("<channel-name>")
    def setOutputForDefaultChannel(self, messageBinder: MqttProducerBinding):
        self.outputChannel1Binding = messageBinder

# Create App Initializer

appInitializer = AppInitializer()
appInitializer.componentScan("")
appInitializer.run()

# YAML Configuration
rcn:
  binders:
    message:
      mqtt:
        producer:
          <channel-name>:
            destination: <topic>
Create Subscriber/Consumer

Let's create Consumer using message binder, using @Input decoration we can create a SubscriberChannel instance that automatically configures a channel to the topic. The simple consumer looks like the below code

@Input("<channel-name>")
def setInputForDefaultChannel(message):
    print(message)

# YAML Configuration

rcn:
  binders:
    message:
      mqtt:
        consumer:
          <channel-name>:
            destination: <topic>