spring-projects / spring-integration

Spring Integration provides an extension of the Spring programming model to support the well-known Enterprise Integration Patterns (EIP)
http://projects.spring.io/spring-integration/
Apache License 2.0
1.54k stars 1.1k forks source link

Improve Reference documentation for Messaging Gateways [INT-4027] #7973

Closed spring-operator closed 1 year ago

spring-operator commented 8 years ago

Manuel Jordan opened INT-4027 and commented

Hello

I am doing some experiments with <int:gateway>

I have read the 8.3 Messaging Gateways section.

I can see many snippet code for xml and many of them using the request-channel attribute. The situation is that the current documentation does not indicate what kind of Channel it should be, seems it should be QueueChannel.

I have the following:

<int:gateway id="gateway"
                     service-interface="com.manuel.jordan.service.IssueService"  
                     >
         <int:method name="send" request-channel="requestChannel" 
                                                    reply-channel="responseChannel" 
                                                    request-timeout="2000" />                            
</int:gateway>  

If I use the requestChannel (QueueChannel) such as:

<int:channel id="requestChannel" 
                    datatype="java.lang.String">
        <int:queue capacity="#{T(com.manuel.jordan.support.Constants).POOL_SIZE}"  />
</int:channel>

The gateway works fine.

But If I use (DirectChannel):

<int:channel id="requestChannel" 
                    datatype="java.lang.String" />        

I get

org.springframework.messaging.MessageDeliveryException: 
Dispatcher has no subscribers for channel 'org.springframework.context.annotation.AnnotationConfigApplicationContext@7a0ac6e3.requestChannel'.; 
nested exception is org.springframework.integration.MessageDispatchingException: 
Dispatcher has no subscribers

Therefore:

(1) Indicate what kind of channels are valid or required for request-channel and reply-channel (Seems mandatory Queue) (2) If is possible use DirectChannel, then add an example with the missing extra configuration need it, it to remove the exception shared above. I am sure the community would be happy with that extra configuration. (I did a research on spring-integration-4.3.xsd and I couldn't find something to fix this) (3) Add a sample with reply-channel, In the 8.3.6 @MessagingGateway Annotation section I can see for example a snippet code about public interface TestGateway (exists a xml code just above that) where some methods of the interface returns something (according with their signature) but in the example never is used the reply-channel. Even if reply-channel is optional if a method returns something, a note about that would be valuable.

Thank you


Affects: 4.2.5

spring-operator commented 8 years ago

Gary Russell commented

Hi Manuel Jordan

You will always get that exception - for any producing endpoint if the channel does not have a consumer subscribed to it - this is not related to the gateway at all.

See Pollable Vs. Subscribable Channels.

spring-operator commented 8 years ago

Manuel Jordan commented

Hi Gary

I've tried use <int:poller> within the <int:method> but is not valid

I mean

<int:channel id="requestChannel" 
                    datatype="java.lang.String">
</int:channel>

<int:gateway id="gateway"
                     service-interface="com.manuel.jordan.service.IssueService" >
     <int:method name="send" request-channel="requestChannel" reply-channel="responseChannel" request-timeout="2000">
            <int:poller cron="#{T(com.manuel.jordan.support.Constants).POLLER_INBOUND_EACH_ONE_SECOND}" />
     </int:method>                           
</int:gateway>           

I get:

Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: 
Line 37 in XML document from class path resource [com/manuel/jordan/channel/queue/01-gateway.xml] is invalid; 
nested exception is org.xml.sax.SAXParseException; 
lineNumber: 37; columnNumber: 98; cvc-complex-type.2.4.a: 
Invalid content was found starting with element 'int:poller'. 
One of '{"http://www.springframework.org/schema/integration":header}' is expected.

And If I use:

<int:gateway id="gateway"
                     service-interface="com.manuel.jordan.service.IssueService">
     <int:method name="send" request-channel="requestChannel" reply-channel="responseChannel" request-timeout="2000" />
     <int:poller cron="#{T(com.manuel.jordan.support.Constants).POLLER_INBOUND_EACH_ONE_SECOND}" /> <!--    
</int:gateway>           

I get

Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: 
Line 37 in XML document from class path resource [com/manuel/jordan/channel/queue/01-gateway.xml] is invalid; 
nested exception is org.xml.sax.SAXParseException; 
lineNumber: 37; columnNumber: 98; cvc-complex-type.2.4.a: 
Invalid content was found starting with element 'int:poller'. 
One of '{"http://www.springframework.org/schema/integration":header}' is expected.

I can have in other place the following and works fine:

<int:service-activator id="serviceActivator"
                                  input-channel="channelA"
                                  output-channel="channelB"                    
                                  ref="messageCheckpointEndpoint"
                                  method="checkpoint">
      <int:poller cron="#{T(com.manuel.jordan.support.Constants).POLLER_INBOUND_EACH_ONE_SECOND}" />    
</int:service-activator>

According with my own experiments and understanding I must use a <int:poller> within a endpoint when the channel is PollableChannel (there exists the receive method), but seems I need something special in a gateway since I am not able to use <int:poller> there.

Thanks

spring-operator commented 8 years ago

Gary Russell commented

No. Pollers appear on just two element types; pollable message sources (generally inbound channel adapters where we "pull" data, e.g. from ftp etc) and on consumers that consume from pollable channels.

Message-driven inbound adapters (JMS, AMQP, all gateways) "push" messages into a message flow - any type of channel is allowed there - the type depends on the configuration of the next component in the flow.

gateway->channel->someOtherComponent-> ....

See this section about the two types of pollers.

The consumer bean for "someOtherComponent" examines the type of the channel it is subscribed to and creates either an EventDrivenConsumer (for a subscribable channel) or a PollingConsumer for a pollable channel.

spring-operator commented 8 years ago

Manuel Jordan commented

Hi Gary

Thanks by the reply

Pollers appear on just two element types; pollable message sources (generally inbound channel adapters where we "pull" data, e.g. from ftp etc)

Yes, I can confirm that, through other own experiments, and I add here the service-activator too (about the list)

and on consumers that consume from pollable channels.

Pls, could you share what kind of consumers are you referring?

I've read your link, sample codes about poller is about the inbound and outbound channels, but nothing about other 'components'.

I am doing now my experiments just with <int:gateway>, no with <int-jms:gateway> yet

Thanks

spring-operator commented 8 years ago

Artem Bilan commented

Manuel, I said you once that we can't copy/paste the whole Internet into our Reference Manual.

I agree that the last one still has its flaws, but the general purpose of each section to concentrate on the specific component or feature.

You can't study Spring Integration components (or even just canonical EIP) in the isolation. Of course, for that <int:gateway> sample you should have something else, e.g. <service-activator> as a consumer on the request-channel. But that is fully different chapter. I find the goal to add cross-links almost from each sentences as a mess.

You should read the EIP Book first of all, then go for a run over the whole Spring Integration Reference Manual to understand the structure. And start to fight with components and their composition. During that process you will come back to the Manual not one time, of course. But sorry, I really don't see reason to mention <service-activator> for the <gateway> description, if the first one is assumed anyway.

BTW, Gary's link has links to EIP description of the Consumer. Not sure in your question then if you read that already...

spring-operator commented 8 years ago

Manuel Jordan commented

Hi Artem

Yes, I remember that advice...

I am going to check again the EIP documentation and SI reference documentation.

Yes, I have my own experiment with a gateway working with a service activator and a queue channel

I did a research on google, is interesting find only the examples working with queue channels.

Sorry to bother you. I prefer receive that kind of answer. It to avoid write a question and perhaps lose the opportunity to detect of a real bug or problem.

Thanks by your understanding.

spring-operator commented 8 years ago

Manuel Jordan commented

I can confirm the following works (Direct Channel):

<int:channel id="requestChannel" 
            datatype="java.lang.String">
<!--        <int:queue capacity="#{T(com.manuel.jordan.support.Constants).POOL_SIZE}"  /> -->
</int:channel>

<int:gateway id="gateway"
                     service-interface="com.manuel.jordan.service.IssueService">
    <int:method name="send" request-channel="requestChannel" reply-channel="responseChannel" request-timeout="2000" />
</int:gateway>

<int:service-activator id="serviceActivator"
                                  input-channel="requestChannel"
                                  output-channel="responseChannel"                     
                                  ref="messageCheckpointEndpoint"
                                  method="checkpoint">
<!--    <int:poller cron="#{T(com.manuel.jordan.support.Constants).POLLER_INBOUND_EACH_ONE_SECOND}" />   -->
</int:service-activator>

Thanks

spring-operator commented 1 year ago

Artem Bilan commented

Closed as nothing to fix any more.