How to instantiate Spring-Integration's jdbc inbound channel adapter programmatically? [duplicate] - java

I am new to Spring integration. I have a JDBC inbound channel adapter as below. When the spring boot application starts below adapater is invoked and starts reading from DB. But i want below to be invoked only after REST API is called
<int-jdbc:inbound-channel-adapter query="select * from accounts" data-source="dataSource" max-rows-per-poll="100" row-mapper="AccountsRowMapper" channel="Accountchannel">
and below rest api as below
#GetMapping(value = "/generateFile")
public void generateFile(String region)
{
// invoked above adapater only after this API is called
}
I am unable to understand how to start reading from DB only after generateFile API is invoked
I am not sure how to

The Inbound Channel Adapter is a thing by itself and it does its work via constant polling cycle. It just does not fit to your requirement.
Since you say you'd like to do something via REST call, then it is an event-driven by end-user action. Therefore you need to look into a <int-jdbc:outbound-gateway> instead which is going to receive a message via its input-channel and do some DB action and produce a reply for you.
See more in docs: https://docs.spring.io/spring-integration/reference/html/jdbc.html#jdbc-outbound-gateway.
In addition you may look into a #MessagingGateway contract to not deal with channels in your REST controller: https://docs.spring.io/spring-integration/reference/html/messaging-endpoints.html#gateway

Related

How to invoke Spring channel adapter from rest api?

I am new to Spring integration. I have a JDBC inbound channel adapter as below. When the spring boot application starts below adapater is invoked and starts reading from DB. But i want below to be invoked only after REST API is called
<int-jdbc:inbound-channel-adapter query="select * from accounts" data-source="dataSource" max-rows-per-poll="100" row-mapper="AccountsRowMapper" channel="Accountchannel">
and below rest api as below
#GetMapping(value = "/generateFile")
public void generateFile(String region)
{
// invoked above adapater only after this API is called
}
I am unable to understand how to start reading from DB only after generateFile API is invoked
I am not sure how to
The Inbound Channel Adapter is a thing by itself and it does its work via constant polling cycle. It just does not fit to your requirement.
Since you say you'd like to do something via REST call, then it is an event-driven by end-user action. Therefore you need to look into a <int-jdbc:outbound-gateway> instead which is going to receive a message via its input-channel and do some DB action and produce a reply for you.
See more in docs: https://docs.spring.io/spring-integration/reference/html/jdbc.html#jdbc-outbound-gateway.
In addition you may look into a #MessagingGateway contract to not deal with channels in your REST controller: https://docs.spring.io/spring-integration/reference/html/messaging-endpoints.html#gateway

How can I return response from RabbitMQ producer to RestController?

I have got two Spring Boot application. First one is REST application. The REST one is communicating with second application through RabbitMQ message queue. I'm sending a request to method with the #GetMapping("/") and this method producing a message to example-queue. A method with #RabbitListener(queues = {"example-queue"}) taking the message and create a object at database. Now, how can I send my response (saved object) to the method with #GetMapping("/")? I need a response from consumer to ResponseEntity.ok();. How can I do that? Thank you.
Just see if you can make the interaction with RabbitMQ consumer as a request-reply pattern.
The #RabbitListener can just return your object and be marked with a #SendTo. This way the framework will look into a replyTo property of the request message.
On the producer side you can just use an AmqpTemplate.convertSendAndReceive().
See more in docs: https://docs.spring.io/spring-amqp/docs/current/reference/html/#request-reply

What is service activator component in spring integration?

I am learning spring integration reading/watching a different stuff but I can't understand what service activator is.
I understood that there are two types of integration:
chanel and gateways. chanel is unidirectional integration but gateways is request/reply model. Gateways can be inbound(our system gets request and sends response) and outbound (our system sends request and receives response)
When I read about gateways I often see termin "service activator"
Could you clarify what does it mean ?
The outbound gateway is essentially a particular case for a service activator abstraction for request/reply scenarios. Another case is an outbound channel adapter, which is a one-way, but still can be treated as a service activator because when we send a message to its inputChannel, we are going to call some code - which we can treat as a service. Therefore activating it.
A general component service activator exists there for all the use-cases which are not covered by particular implementation. Let's imaging you need to call some REST service. Right, you can use an HTTP Outbound Gateway with some specific options. Or you can write some custom code which uses a RestTemplate to call that service. you wrap your code into a service activator configuration and you end up with the same behavior for the whole integration solution.
A service activator is a call to a method in a bean.
<service-activator ref="myService" method="aMethod"/>
will call
#Service
public class MyService {
public A aMethod(#Header(value = "param1") String param){
//code
}
}
#Header annotation allows to use an existing value in the header. That is an example.
You can also use it like this:
<service-activator expression="#myService.aMethod('My param')"/>

How to implement one-way operation in Java Web Services?

How to implement one-way operation in Web Services (using Java or Spring annotations)?
I have tried to add one way as given below
#WebService
public interface DanduServices {
#Oneway
public void saveDanduInformation(#WebParam(name = "serv") ServDTO Serv, #WebParam(name = "dandu") DanduDTO danduDto);
but it is still request-response not asynchronus or one way.
Could anyone suggest to make a operation one-way in service endpoint and let other operations behave as per request-response?
You need to think in terms of the protocol as well though. In HTTP when you send a request you wait for a response, if no response comes back after an amount of time then you will receive a time-out error. So when you talk about one-way (you should rather say async request maybe) you really need to specify exactly what you mean. Do you want to have confirmation that your message was received i.e. have the server respond back with an OK status code and go off and complete it's task but you not wait for the task to be completed? Then you would need to spawn another thread. Spring has AOP for this the same way it has for transactions with #Transactional. Instead you annotated your method with #Async and return a Future<Something>. You'll also need #EnableAsync in your config. Refer to this article for an example Hot To Do #Async
If you don't even care about if the server received your request you don't want to use TCP/HTTP but instead UDP which is used in VOIP (phone over internet) for instance and is quicker, but it will depend on your client.

Spring Integration Gateway with no arguments

On my gateway, I have a method
#Gateway
String commsTest();
The idea is that I can call commsTest from the bean and use spring integration to wire it up to the service activator that will check comms.
When I do that I get a receive is not supported, because no pollable reply channel has been configured error. I realise that this is because a method with no params means "I am trying to poll a message from the channel"
This is a two part question.
What does it mean to poll a message from the channel.
How can I get the functionality I want.
Spring Integration currently has no concept of a message without a payload. By default, a gateway method with no arguments implies you want to receive data (rather than sending data or sending and receiving data).
You can change that default behavior, as described in the reference documentation.

Categories