Connection not found when processing reply GenericMessage - java

Try to set up Spring Boot TCP Server with spring-integration-ip, but when send message to the server always get the error message:
2021-06-03 23:58:36.916 ERROR 35752 --- [pool-1-thread-4] o.s.i.ip.tcp.TcpInboundGateway : Connection not found when processing reply GenericMessage [payload=byte[5], headers={ip_tcp_remotePort=51436, ip_connectionId=localhost:51436:10001:dbc9ca03-a509-4a66-9bbd-020478794bbd, ip_localInetAddress=/0:0:0:0:0:0:0:1, ip_address=0:0:0:0:0:0:0:1, id=3c446dc8-f417-e387-a4e4-42c023da0d4f, ip_hostname=localhost, timestamp=1622746716916}] for GenericMessage [payload=byte[3], headers={ip_tcp_remotePort=51436, ip_connectionId=localhost:51436:10001:dbc9ca03-a509-4a66-9bbd-020478794bbd, ip_localInetAddress=/0:0:0:0:0:0:0:1, ip_address=0:0:0:0:0:0:0:1, id=59caa1c3-20df-57c0-d1dc-81c2b0adfe0d, ip_hostname=localhost, timestamp=1622746716916}]
Here is my TcpServerConfig file:
#Configuration
#EnableIntegration
public class TcpServerConfig {
#Value("${tcp.server.port}")
private int port;
#Bean
public AbstractServerConnectionFactory serverConnectionFactory() {
TcpNioServerConnectionFactory serverConnectionFactory = new TcpNioServerConnectionFactory(port);
serverConnectionFactory.setUsingDirectBuffers(true);
return serverConnectionFactory;
}
#Bean
public MessageChannel inboundChannel() {
return new DirectChannel();
}
#Bean
public TcpInboundGateway inboundGateway(AbstractServerConnectionFactory serverConnectionFactory,
MessageChannel inboundChannel) {
TcpInboundGateway tcpInboundGateway = new TcpInboundGateway();
tcpInboundGateway.setConnectionFactory(serverConnectionFactory);
tcpInboundGateway.setRequestChannel(inboundChannel);
return tcpInboundGateway;
}
}
And TcpServerEnpoint file:
#Component
#MessageEndpoint
public class TcpServerEndpoint {
#ServiceActivator(inputChannel = "inboundChannel")
public byte[] process(byte[] message) {
System.out.println(Arrays.toString(message));
return "Hello".getBytes();
}
}
I'm trying to make simple request -> response TCP server. When message has been sent it print out in debug console, but also throws the error.

Here is what I have for you:
#SpringBootApplication
public class So67827589Application {
public static void main(String[] args) {
SpringApplication.run(So67827589Application.class, args);
}
#Bean
public AbstractServerConnectionFactory serverConnectionFactory() {
TcpNioServerConnectionFactory serverConnectionFactory = new TcpNioServerConnectionFactory(7777);
serverConnectionFactory.setUsingDirectBuffers(true);
return serverConnectionFactory;
}
#Bean
public MessageChannel inboundChannel() {
return new DirectChannel();
}
#Bean
public TcpInboundGateway inboundGateway(AbstractServerConnectionFactory serverConnectionFactory,
MessageChannel inboundChannel) {
TcpInboundGateway tcpInboundGateway = new TcpInboundGateway();
tcpInboundGateway.setConnectionFactory(serverConnectionFactory);
tcpInboundGateway.setRequestChannel(inboundChannel);
return tcpInboundGateway;
}
#ServiceActivator(inputChannel = "inboundChannel")
public byte[] process(byte[] message) {
System.out.println(Arrays.toString(message));
return "Hello".getBytes();
}
}
Then I go to command line and do:
telnet localhost 7777
and type anything and get Hello back. Then I can type more and more - and Hello comes back to me. Always!
So, everything works as expected. Spring Boot 2.5.0.

Related

ActiveMQ messages from the topic are not received

I am having a weird situation. I am listening to a topic
I am able to listen to the message as long as the server is up and running. But the soon I stop server and messages are arriving in the queue and when the server is up again I am not able to consume those messages.
#Configuration
public class ConnectionFactoryConfig {
#Value("${jsa.activemq.broker.url}")
String brokerUrl;
#Value("${jsa.activemq.borker.username}")
String userName;
#Value("${jsa.activemq.borker.password}")
String password;
/*
* Initial ConnectionFactory
*/
#Bean
public ConnectionFactory connectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setBrokerURL(brokerUrl);
connectionFactory.setUserName(userName);
connectionFactory.setPassword(password);
return connectionFactory;
}
// #Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
// converter.setTypeIdPropertyName("_type");
return converter;
}
#Bean
public JmsListenerContainerFactory<?> jsaFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setPubSubDomain(true);
// factory.setMessageConverter(jacksonJmsMessageConverter());
configurer.configure(factory, connectionFactory);
factory.setSessionTransacted(true);
factory.setSubscriptionDurable(true);
factory.setClientId("TEST_CLIENT");
return factory;
}
}
Subscriber
#Component
public class JmsSubcriber {
#JmsListener(destination = "${jsa.activemq.topic}")
public void receive(String msg) {
System.out.println(new Date() + "::Recieved Message: " + msg);
}
}
Property files
jsa.activemq.broker.url=tcp://localhost:61616
jsa.activemq.borker.username=admin jsa.activemq.borker.password=admin
jsa.activemq.topic=jsa-topic spring.jms.pub-sub-domain=true
See the messages in the queue I can se
But on starting the server I am not getting it.

Handle the exceptions in RabbitMQ Spring Boot Application

I am using Spring Boot 1.4.1-RELEASE and RabbitMQ 3.2.3. My Application class looks like this -
#SpringBootApplication
#EnableAutoConfiguration
public class EventStoreMessageDeliveryApplication {
public final static String queueName = "customer.default.queue"; // spring-boot
#Bean
Queue queue() {
return new Queue(queueName, true);
}
#Bean
FanoutExchange exchange() {
return new FanoutExchange("customer.events.fanout.exchange", true, false); // spring-boot-exchange
}
#Bean
Binding binding() {
return new Binding(queueName, Binding.DestinationType.QUEUE, "customer.events.fanout.exchange", "*.*", null);
}
#Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
connectionFactory.setPublisherConfirms(true);
return connectionFactory;
}
#Bean
SimpleMessageListenerContainer container(MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory());
container.setQueueNames(queueName);
container.setMessageListener(listenerAdapter);
container.setRecoveryBackOff(new ExponentialBackOff(3000, 2));
return container;
}
#Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(EventStoreMessageDeliveryApplication.class, args);
}
}
And my listener class looks like -
#Component
public class Receiver {
private CountDownLatch latch = new CountDownLatch(1);
public void receiveMessage(String message) {
System.out.println("Received <" + message + ">");
// do something
latch.countDown();
}
public CountDownLatch getLatch() {
return latch;
}
}
I want to handle the exceptions like connection refused which may come when the broker is down. How can I handle such exceptions? I am not sure where I can get the handle for the exceptions.
You can create a SimpleRabbitListenerContainerFactory. This is basically a listener for events from RabbitConnectionFactory.
#Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setErrorHandler(rabbitErrorHandler());
return factory;
}
rabbitErrorHandler() can return a bean of implementation of org.springframework.util.ErrorHandler.
Reference docs
I have a suggestion and it could work out. Since you want to have an exception of connection refused against the RabbitMQ broker, it is up to the client to catch the exception.
In your example, which looks like the one from SpringIO docs, I would assume you could make the exception handling in the main (not recommended though):
#Component
public class Runner implements CommandLineRunner {
private final RabbitTemplate rabbitTemplate;
private final Receiver receiver;
public Runner(Receiver receiver, RabbitTemplate rabbitTemplate) {
this.receiver = receiver;
this.rabbitTemplate = rabbitTemplate;
}
#Override
public void run(String... args) throws Exception {
System.out.println("Sending message...");
try {
rabbitTemplate.convertAndSend(Application.topicExchangeName, "foo.bar.baz", "Hello from RabbitMQ!");
receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);
}catch(AmqpException the_exception) {
System.out.printl("Connection refused. Problem thrown when trying to connecto the RabbitMQ");
}
}
}
The AmqpException comes from the docs of the convertAndSend() method, which is being thrown if something went bad. Here you can capture your own custom message.
I hope this is what you are looking for or atleast guides you the correct destination.
/A

ERR Timed out after 1m0s: health check never passed

I am getting this exception after some 2-3 minutes of proper run of my app on cloud.I added timeout : 180 in manifest.yml file but the error still persists.
On STS console, I get the log as :
Execution failed for task ':cfPush'.> Application TestApp start timed out
Can anyone help me out in this please
Code:
#SpringBootApplication
public class SftpJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(SftpJavaApplication.class)
.web(false)
.run(args);
}
#Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost("ip");
factory.setPort(port);
factory.setUser("user");
factory.setPassword("pwd");
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(factory);
}
#Bean
#Transformer(inputChannel = "stream",outputChannel="data")
public org.springframework.integration.transformer.Transformer transformer () {
return new org.springframework.integration.transformer.StreamTransformer("UTF-8");
}
#Bean
#InboundChannelAdapter(value = "stream", poller = #Poller(fixedDelay = "1000", maxMessagesPerPoll = "1"))
public MessageSource<InputStream> ftpMessageSource() {
SftpStreamingMessageSource messageSource = new SftpStreamingMessageSource(template(), null);
messageSource.setRemoteDirectory("/test1/test2/test3");
messageSource.setFilter(new SftpPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(),
"streaming"));
return messageSource;
}
#Bean
public SftpRemoteFileTemplate template() {
return new SftpRemoteFileTemplate(sftpSessionFactory());
}
#Bean
#ServiceActivator(inputChannel = "data" )
public MessageHandler handler() {
return new MessageHandler() {
#Override
public void handleMessage(Message<?> message) throws MessagingException {
System.out.println(">>>>>>>>>>>>>"+message.getPayload()); //instead of a print the message is published to rabbit mq
}
};
}
}
There is another class which connects to a rabbit mq service on cloud and consumes the message

Spring and AMQP RabbitMQ topic exchange not working

I'm trying to set up topic exchange on my spring app.
Here's my context configuration:
#Configuration
public class IntegrationConfig {
public final static String queueName = "my-queue";
#Bean
AmqpAdmin amqpAdmin(ConnectionFactory connectionFactory) {
return new RabbitAdmin(connectionFactory);
}
#Bean
Queue queue() {
return new Queue(queueName);
}
#Bean
TopicExchange exchange() {
return new TopicExchange("my-exchange", false, true);
}
#Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("ru.interosite.*");
}
#Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queueName);
container.setMessageListener(listenerAdapter);
return container;
}
#Bean
ImageUploadReceiver receiver() {
return new ImageUploadReceiver();
}
#Bean
MessageListenerAdapter listenerAdapter(ImageUploadReceiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
}
This is receiver class:
public class ImageUploadReceiver {
private CountDownLatch latch = new CountDownLatch(1);
public void receiveMessage(String message) {
System.out.println("Received ");
latch.countDown();
}
public CountDownLatch getLatch() {
return latch;
}
}
This is sender code:
#RequestMapping("/sendmessage")
#ResponseBody
public String sendMessage() {
rabbitTemplate.convertAndSend("ru.interosite.1", "ttt1233");
try {
imageUploadReceiver.getLatch().await(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Msg received";
}
So I'm sending message to topic exchange using binding key "ru.interosite.1" to the queue that was bound with pattern "ru.interosite.*". I used these key and pattern when tried sample from https://www.rabbitmq.com/tutorials/tutorial-five-java.html and they worked fine.
But inside String AMQP it does not work, i.e. receiver never gets called. It called only if binding key and pattern are completely the same as if I were using DirectExchange.
Am I missing something here?
You don't show the config for the RabbitTemplate, but I guess it is with default options.
To send a message to the my-exchange you must specify it directly:
rabbitTemplate.convertAndSend("my-exchange", "ru.interosite.1", "ttt1233");
You can also set the exchange in the rabbit template like this:
#Configuration
public class IntegrationConfig {
// ... as above
#Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setExchange("my-exchange");
return template;
}
}
So you can send the message with:
public class MyController {
#Autowired
RabbitTemplate rabbitTemplate;
#RequestMapping("/sendmessage")
#ResponseBody
public String sendMessage() {
rabbitTemplate.convertAndSend("ru.interosite.1", "ttt1233");
// ... as above
}
}

Spring Integration : TcpInboundGateway read stream closed before #MessageEndpoint writes to out stream

I am using spring boot as per examples for TcpInboundGateway, but have discovered the behaviour is slightly different than a hand coded a piece of TCP code I am replacing.
Specifically when using netcat, nc exits before receiving an answer, because the TcpInboundGateway read steam is closed, before any write occurs, causing nc to exit.
Can closing the read stream be delayed until the write has completed?
Here is the code:
#Configuration
#EnableIntegration
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = SpringApplication.run(Application.class);
}
#Bean
TcpNetServerConnectionFactory cf () {
return new TcpNetServerConnectionFactory(9876);
}
#Bean
TcpInboundGateway tcpGate() {
TcpInboundGateway gateway = new TcpInboundGateway();
gateway.setConnectionFactory(cf());
gateway.setRequestChannel(requestChannel());
return gateway;
}
#Bean
public MessageChannel requestChannel() {
return new DirectChannel();
}
#MessageEndpoint
public static class Echo {
#ServiceActivator(inputChannel = "requestChannel")
public String echo(byte [] in) {
return "echo: " + new String(in);
}
}
#Autowired
private Environment env;
}
So I figured out it was probably the stream terminator character. Did some fiddling and found that using ByteArrayRawSerializer solves my problem.
#Bean TcpNetServerConnectionFactory cf () {
TcpNetServerConnectionFactory tcpNetServerConnectionFactory = new TcpNetServerConnectionFactory(9876);
tcpNetServerConnectionFactory.setDeserializer(new ByteArrayRawSerializer());
return tcpNetServerConnectionFactory;
}

Categories

Resources