Using a gateway from another application
I am using spring-boot, spring-integration and hornetq.
I have a "app-bridge" messaging center bridge project and a number of other projects that request information from the bridge. All projects are deployed as "war" files on the tomcat server.
I need to create a synchronous request from "app-1" to the application-bridging application (the "application-bridging" makes an MQ request to the remote application to respond, and I don't want to expose it gets data for every single application, i.e. only the bridge application needs to know how to get the response).
In the "app-bridge" I have the following gateway installed.
<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 I need to run this from the "app-1" project.
How can I achieve this?
UPDATE for @Gary
integration of xml file in the project of the bridge application.
<?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 military applications (app-1, app-2, app-3) to be able to call the "com.example.bridge.as400.As400SendAndReceive" gateway as defined in the "bridge" application. it is important that if you say that "application-1" and "application-2" are requesting a message, it is sent back to the correct requestor. The As400 message does not support HEADERS, so it is sent as a simple MQSTR.
source to share
<int:gateway/>
creates a local java API; you cannot use it yourself to query the remote system.
Your bridge application must have one <int-jms:inbound-gateway/>
to serve JMS requests.
Other applications will use an explorer <int:gateway/>
to send requests to <int-jms:outbound-gateway/>
, configured to send messages to the same recipient that is listening on the application's incoming gateway.
EDIT
Remote applications cannot "call" a gateway in a bridged application; it is a simple Java object, visible only in the bridge application.
You need external communication between app-n and app-bridge. You can choose the technology of your choice, JMS, RMI, RabbitMQ, HTTP, etc. Etc.
You will need <int-x:outbound-gateway/>
in app-n and <int-x:inbound-gateway/>
in the bridge app.
Where x
is what you decide to use for communication. Explore the documentation to make your choice. Considering that you are already using JMS to communicate with the AS / 400, JMS may be a better choice (but you need different queues).
source to share