Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Gateway from another application

I am using spring-boot, spring-integration and hornetq.

I have a central messaging bridge project "app-bridge" and a number of other projects that request information from the bridge. All projects are deployed as "war" files to a tomcat server.

I need to create a synchronous request from "app-1" to the "app-bridge" application ("app-bridge" makes an MQ request to a remote application for the response and I don't want to expose the way it gets the data to each individual application. ie only "app-bridge" should know how to get the response).

In "app-bridge" I have the following gateway defined.

<int:gateway service-interface="org.company.SendAndReceive"  
    default-request-channel="synchronousOutChannel" 
    default-reply-channel="synchronousInChannel"
    default-reply-timeout="30000"
    default-request-timeout="30000">
</int:gateway>

This works fine when run from the "app-bridge" project.

@Autowired
private final SendAndReceive sendAndReceive;

...

@Scheduled(fixedDelay = 30000L)
public void testing() {
    sendAndReceive.send("HELLO");
    String resposne = sendAndReceive.receive();
    System.out.println(resposne); //prints the response or null if a timeout occurred
}

The problem is that I need to run this from the "app-1" project.

How can I achieve this?

UPDATE for @Gary

integration xml file in the app-bridge project.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-file="http://www.springframework.org/schema/integration/file"
    xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
    xmlns:int-http="http://www.springframework.org/schema/integration/http"
    xsi:schemaLocation="
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.1.xsd
        http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file-4.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
        http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">

    <!--************************* SENDING ********************************-->

    <!-- handle errors -->
    <int:channel id="as400SynchronousOutFailedChannel" />
    <int-jms:outbound-channel-adapter 
        id="as400SynchronousOutFailed" 
        destination-name="as400.synchronous.out.failed" 
        channel="as400SynchronousOutFailedChannel"
        connection-factory="jmsConnectionFactory"/>


    <!-- Read local messages from hornet -->
    <int:channel id="as400SynchronousOutChannel" />

    <int-jms:message-driven-channel-adapter
        id="jmsSynchronousAS400Out"
        acknowledge="transacted"
        destination-name="as400.synchronous.out"
        channel="as400SynchronousOutChannel"
        connection-factory="jmsConnectionFactory"
        error-channel="as400SynchronousOutFailedChannel"
        concurrent-consumers="1"
        pub-sub-domain="false" /> 

    <!-- Send messages to AS/400 -->
    <int-jms:outbound-channel-adapter
        id="jmsSynchronousOut"
        destination="as400SynchronousOutQueue"
        channel="as400SynchronousOutChannel"
        jms-template="as400JmsTemplate">
        <int-jms:request-handler-advice-chain>
            <int:retry-advice max-attempts="3">
                <int:exponential-back-off initial="2000" multiplier="2" />
            </int:retry-advice>
        </int-jms:request-handler-advice-chain>
    </int-jms:outbound-channel-adapter>

    <!-- Connection to remote AS/400 Queue -->
    <bean id="as400SynchronousOutQueue" class="com.ibm.mq.jms.MQQueue">
        <constructor-arg value="AS400.SYNCHRONOUS.IN" />
         <property name="targetClient">
            <bean id="com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>
        </property>
    </bean>

    <!-- Place to put messages that have failed -->
    <int-jms:outbound-channel-adapter 
        id="jmsAS400SynchronousOutFailed" 
        destination-name="as400.synchronous.out.failed" 
        channel="as400SynchronousOutFailedChannel"
        connection-factory="jmsConnectionFactory"/>


<!--************************* RECEIVING ********************************-->

    <!-- handle errors -->
    <int:channel id="as400SynchronousInFailedChannel" />
    <int-jms:outbound-channel-adapter 
        id="as400SynchronousInFailed" 
        destination-name="as400.synchronous.in.failed" 
        channel="as400SynchronousInFailedChannel"
        connection-factory="jmsConnectionFactory"/>

    <!-- Receive messages from AS/400 -->
    <int:channel id="as400SynchronousInChannel">
        <int:rendezvous-queue/>
    </int:channel>
    <int-jms:message-driven-channel-adapter
        id="jmsAS400SynchronousIn"
        acknowledge="transacted"
        destination="as400SynchronousInQueue"
        channel="as400SynchronousInChannel"
        connection-factory="as400ConnectionFactory"
        error-channel="as400SynchronousInFailedChannel"/> 

    <!-- Connection to remote AS/400 Queue -->
    <bean id="as400SynchronousInQueue" class="com.ibm.mq.jms.MQQueue">
        <constructor-arg value="AS400.SYNCHRONOUS.OUT" />
    </bean>

    <int:gateway service-interface="com.example.bridge.as400.As400SendAndReceive"  
        default-request-channel="as400SynchronousOutChannel" 
        default-reply-channel="as400SynchronousInChannel"
        default-reply-timeout="30000"
        default-request-timeout="30000">
    </int:gateway>

</beans>

com.example.bridge.as400.As400SendAndReceive java class.

public interface As400SendAndReceive {

    public void send(final String message);

    public String receive();

}

So I want all my other war applications (app-1, app-2, app-3) to be able to call the "com.example.bridge.as400.As400SendAndReceive" gateway somehow that is defined in the "app-bridge" war. It is also important that if say both "app-1" and "app-2" request a message, it is sent back to the correct requestor. The As400 message does not support HEADERS so it is being sent as a plain MQSTR.

like image 850
jax Avatar asked May 11 '26 00:05

jax


1 Answers

The <int:gateway/> generates a local java API; you can't use it alone for requests to a remote system.

Your app-bridge should have a <int-jms:inbound-gateway/> to service requests over JMS.

The other apps would use an <int:gateway/> wired to send requests to an <int-jms:outbound-gateway/> configured to send messages to the same destination the app-1 inbound gateway is listening on.

EDIT:

The remote apps can't "call" the gateway in app-bridge; it's a simple java object that's only visible within app-bridge.

You need some kind of external communication between app-n and app-bridge. You can choose the technology of your choice, JMS, RMI, RabbitMQ, HTTP, etc, etc.

You need an <int-x:outbound-gateway/> in app-n and an <int-x:inbound-gateway/> in app-bridge.

Where x is whatever you choose to use for the communication. Explore the documentation to make your choice. Given you are already using JMS to talk to the AS/400, maybe JMS would be the best choice (but you need different queues).

like image 142
Gary Russell Avatar answered May 12 '26 14:05

Gary Russell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!