Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: How to create a point to point channel in code ?

  1. #1
    Join Date
    Aug 2008
    Posts
    15

    Default How to create a point to point channel in code ?

    Hi,

    I do not see in the documentation which class corresponds to a point to point channel. All channel types described in the documentation have a corresponding class in the javadoc, implementing MessageChannel, but not point to point. Which factory should be used to create teh equivalent of <channel> ?

  2. #2
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    The default channel type created by <channel/> is currently a QueueChannel.

    We are going to be refactoring the channel namespace support to emphasize the fact that there are 2 main types of channel: Point-to-Point and Publish-Subscribe.
    Code:
    <channel id="p2pChannel"/>
    
    <publish-subscribe-channel id="pubsubChannel"/>
    Then, the plan is to support buffering on point-to-point channels by adding a queue. The idea is that such configuration will be more explicit and therefore more clear. After these changes, the configuration should look something like the following:
    Code:
    <channel id="directChannel"/>
    
    <channel id="queueChannel">
        <queue capacity="100"/>
    </channel>
    
    <channel id="priorityQueue">
        <priority-queue capacity="100" comparator="someComparator"/>
    </channel>
    
    <channel id="rendezvousQueue">
        <rendezvous-queue/>
    </channel>
    As you can see above the same channel types will be supported. The first one now becomes 'direct' (has no queue, subscribers will be invoked in the sender's thread). The type of queue is what differentiates the other types (queue (FIFO), priority, and rendezvous).

    Any feedback on this plan would be greatly appreciated.

    Regards,
    Mark

  3. #3
    Join Date
    Aug 2008
    Posts
    15

    Default

    This is fine for me.

    BTW, my use case is more about dynamically creating channels and mixing elements created through configuration and elements created through code.

    On problem I had was to access the message bus through code. I solved the problem by using

    Code:
      <bean id="messageBus" class="org.springframework.integration.bus.DefaultMessageBus">
        <property name="autoStartup" value="true"/>
      </bean>
    instead of

    Code:
      <integration:message-bus/>
    but I guess there is a better way to get a reference to the message bus !

  4. #4
    Join Date
    Aug 2008
    Posts
    15

    Default

    BTW, I couln't find a way to give a channel a name through code. MessageChannel has a getName() method but no setName().

    My use case is to dynamically create a channel with a name, and use it to create a RmiGateway. Another application is then supposed to dynamically create a RmiHandler and connect to the gateway. For this, it needs the remote channel name, but I can't figure how to set it. (Everything else seems to be working fine!)

  5. #5
    Join Date
    Aug 2008
    Posts
    15

    Default

    In fact, the problem is simply that I need to access the implementation QueueChannel) to set teh beanName.

    This works but is not very clean. I think it would be fine to be able to write :

    Code:
            MessageChannel channel = new QueueChannel();
            channel.setName("aChannelName");
    instead of this, I have to write :

    Code:
            QueueChannel channel = new QueueChannel();
            channel.setBeanName("aChannelName");

  6. #6
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    The AbstractMessageChannel class implements BeanNameAware, and that defines a "setBeanName()" method. This is normally invoked directly by the framework (e.g. when using namespace support or <bean/> definitions). You can call channel.setBeanName("whatever") yourself.

  7. #7
    Join Date
    Aug 2008
    Posts
    15

    Default

    Thanks Mark. This is obviously better. But If I had choice, I think I would prefer:

    Code:
            Channel channel = new QueueChannel();
            channel.setName("aChannelName");
    rather than:

    Code:
            AbstractChannel channel = new QueueChannel();
            channel.setName("aChannelName");
    Not a big deal anyway!

  8. #8
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    It looks like our previous messages were interleaved. I understand your preference there. However, in this case, I think defining that setter on the interface is violating encapsulation (you should not care how the name is determined... it might be auto-generated). Any time that you are writing code that creates a concrete instance, you obviously depend on the implementation type you are creating so it's fine to use it and thus have access to the methods that are encapsulated by that concrete type (or in this case its abstract superclass):
    Code:
    QueueChannel channel = new QueueChannel();
    channel.setBeanName("whatever");
    This is very different than providing a method that should be accessible to *users* of the instance at runtime where dependency-injection can be used, and the code should only depend on the interface:
    Code:
    public void setChannel(MessageChannel channel) {
        String channelName = channel.getName();
        ...
    }

  9. #9
    Join Date
    Aug 2008
    Posts
    15

    Default

    I agree. But as a user of the channel might need to find the channel by name, I think it would be practical to have the name be part of the interface. I understand that what is used here is the bean name, and not a "channel name", but as there are some cases where one must have a reference to the channel, I think a channel should have a name, be it the same as the bean name or not.

    My use case is as follow :

    Several applications C1 ... Cn connect to an application M on a common channel available through an RMI gateway. Each of these application in turn make a specific channel available to M through an RMI Gateway giving M the name of the channel they make available. When M connects back to C1 .. Cn, it must know the remote channel name (which is unknown at configuration time).

    Is there another way to reference the channel when creating the RMI Holder (in M) that connect to the Gateway (in C1 ... Cn)? If not, shouldn't the channel name be part of the channel interface?

  10. #10
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    I don't fully understand what you mean by "shouldn't the channel name be part of the channel interface?" since the getName() method is defined on the interface and is therefore available anywhere you are using the channel. If you are programmatically creating channels, then you set the name at creation time. Ideally, the name should not change after creation and exposing a setter on the interface is therefore dangerous. Also, in general, creating channels "on-the-fly" is not a very typical use-case. Perhaps you can explain a little bit more about your channel creation process and specifically why it's necessary at runtime?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •