INT-3883: UDP: destination and socket expressions

JIRA: https://jira.spring.io/browse/INT-3883

UDP Outbound Channel Adapter is able to use given UDP Inbound Adapters
server socket (outgoing packets will have source port same as incoming
packets destination port).

* Introduce `destinationExpression` instead of hard-coded `host/port` logic in the `DatagramPacketMessageMapper`
* Make `UnicastSendingMessageHandler.destinationExpression` mutually exclusive with `host/port` pair
* Move `socketExpression` to the setter as it is absolutely different option from the `destination`
* Make `UnicastSendingMessageHandler` expressions logic based on the `requestMessage`

INT-3883 Code review fixes.

Further polishing

Polishing according PR comments

Rework the String socket address logic just to the expected `URI` style.
Accept `2016` for changed classes.
This commit is contained in:
Marcin Pilaczynski
2015-11-09 22:09:02 +01:00
committed by Artem Bilan
parent 41c48548f1
commit 8bf8caa22e
16 changed files with 318 additions and 83 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.integration.ip.udp;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
@@ -34,6 +35,7 @@ import org.apache.commons.logging.LogFactory;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.integration.ip.IpHeaders;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
@@ -98,7 +100,9 @@ public class DatagramPacketMulticastSendingHandlerTests {
executor.execute(catcher);
assertTrue(listening.await(10000, TimeUnit.MILLISECONDS));
MulticastSendingMessageHandler handler = new MulticastSendingMessageHandler(multicastAddress, testPort);
handler.setBeanFactory(mock(BeanFactory.class));
handler.setLocalAddress(this.multicastRule.getNic());
handler.afterPropertiesSet();
handler.handleMessage(MessageBuilder.withPayload(payload).build());
assertTrue(received.await(10000, TimeUnit.MILLISECONDS));
handler.stop();
@@ -176,6 +180,7 @@ public class DatagramPacketMulticastSendingHandlerTests {
new MulticastSendingMessageHandler(multicastAddress, testPort, true, true, "localhost", 0, 10000);
handler.setLocalAddress(this.multicastRule.getNic());
handler.setMinAcksForSuccess(2);
handler.setBeanFactory(mock(BeanFactory.class));
handler.afterPropertiesSet();
handler.start();
waitAckListening(handler);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ import org.springframework.messaging.Message;
/**
* @author Mark Fisher
* @author Gary Russell
* @author Marcin Pilaczynski
* @since 2.0
*/
public class DatagramPacketSendingHandlerTests {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.handler.ServiceActivatingHandler;
@@ -53,6 +55,7 @@ import org.springframework.messaging.SubscribableChannel;
*
* @author Gary Russell
* @author Artem Bilan
* @author Marcin Pilaczynski
* @since 2.0
*
*/
@@ -326,12 +329,30 @@ public class UdpChannelAdapterTests {
adapter.stop();
}
@Test
public void testSocketExpression() throws Exception {
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("testIp-socket-expression-context.xml", getClass());
UnicastReceivingChannelAdapter adapter = context.getBean(UnicastReceivingChannelAdapter.class);
SocketTestUtils.waitListening(adapter);
int receiverServerPort = adapter.getPort();
DatagramPacket packet = new DatagramPacket("foo".getBytes(), 3);
packet.setSocketAddress(new InetSocketAddress("localhost", receiverServerPort));
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.receive(packet);
assertEquals("FOO", new String(packet.getData()));
assertEquals(receiverServerPort, packet.getPort());
context.close();
}
private class FailingService {
@SuppressWarnings("unused")
public String serviceMethod(byte[] bytes) {
throw new RuntimeException("Failed");
}
}
}

View File

@@ -0,0 +1,22 @@
<?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-ip="http://www.springframework.org/schema/integration/ip"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/ip http://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd">
<int-ip:udp-inbound-channel-adapter id="inbound" port="0" channel="in" />
<int:channel id="in" />
<int:transformer expression="new String(payload).toUpperCase()" input-channel="in" output-channel="out"/>
<int:channel id="out" />
<int-ip:udp-outbound-channel-adapter socket-expression="@inbound.socket"
destination-expression="'udp://localhost:' + headers['ip_packetAddress'].port"
channel="out" />
</beans>