GH-3410: Add UDP SocketCustomizer
Resolves https://github.com/spring-projects/spring-integration/issues/3410 **cherry-pick to 5.3.x** * Doc polishing.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -133,6 +133,8 @@ public abstract class IpAdapterParserUtils {
|
||||
|
||||
public static final String CONNECT_TIMEOUT = "connect-timeout";
|
||||
|
||||
public static final String UDP_SOCKET_CUSTOMIZER = "socket-customizer";
|
||||
|
||||
private IpAdapterParserUtils() {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -51,6 +51,8 @@ public class UdpInboundChannelAdapterParser extends AbstractChannelAdapterParser
|
||||
IpAdapterParserUtils.TASK_EXECUTOR);
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element,
|
||||
IpAdapterParserUtils.LOOKUP_HOST);
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element,
|
||||
IpAdapterParserUtils.UDP_SOCKET_CUSTOMIZER);
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class UdpOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = parseUdp(element, parserContext);
|
||||
IpAdapterParserUtils.addCommonSocketOptions(builder, element);
|
||||
@@ -86,6 +87,8 @@ public class UdpOutboundChannelAdapterParser extends AbstractOutboundChannelAdap
|
||||
IpAdapterParserUtils.TASK_EXECUTOR);
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element,
|
||||
"socket-expression", "socketExpressionString");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element,
|
||||
IpAdapterParserUtils.UDP_SOCKET_CUSTOMIZER);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.function.Function;
|
||||
|
||||
import org.springframework.integration.dsl.MessageHandlerSpec;
|
||||
import org.springframework.integration.expression.FunctionExpression;
|
||||
import org.springframework.integration.ip.udp.SocketCustomizer;
|
||||
import org.springframework.integration.ip.udp.UnicastSendingMessageHandler;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
@@ -133,4 +134,15 @@ public abstract class AbstractUdpOutboundChannelAdapterSpec<S extends AbstractUd
|
||||
return _this();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the socket.
|
||||
* @param customizer the customizer.
|
||||
* @return the spec.
|
||||
* @since 5.3.3
|
||||
*/
|
||||
public S configureSocket(SocketCustomizer customizer) {
|
||||
this.target.setSocketCustomizer(customizer);
|
||||
return _this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.concurrent.Executor;
|
||||
|
||||
import org.springframework.integration.dsl.MessageProducerSpec;
|
||||
import org.springframework.integration.ip.udp.MulticastReceivingChannelAdapter;
|
||||
import org.springframework.integration.ip.udp.SocketCustomizer;
|
||||
import org.springframework.integration.ip.udp.UnicastReceivingChannelAdapter;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
|
||||
@@ -50,7 +51,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec soTimeout(int soTimeout) {
|
||||
this.target.setSoTimeout(soTimeout);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +61,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec taskScheduler(TaskScheduler taskScheduler) {
|
||||
this.target.setTaskScheduler(taskScheduler);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +71,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec soReceiveBufferSize(int soReceiveBufferSize) {
|
||||
this.target.setSoReceiveBufferSize(soReceiveBufferSize);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +81,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec receiveBufferSize(int receiveBufferSize) {
|
||||
this.target.setReceiveBufferSize(receiveBufferSize);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +91,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec lengthCheck(boolean lengthCheck) {
|
||||
this.target.setLengthCheck(lengthCheck);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,7 +101,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec localAddress(String localAddress) {
|
||||
this.target.setLocalAddress(localAddress);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,7 +111,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec poolSize(int poolSize) {
|
||||
this.target.setPoolSize(poolSize);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +121,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec taskExecutor(Executor taskExecutor) {
|
||||
this.target.setTaskExecutor(taskExecutor);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +131,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec socket(DatagramSocket socket) {
|
||||
this.target.setSocket(socket);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +141,7 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec soSendBufferSize(int soSendBufferSize) {
|
||||
this.target.setSoSendBufferSize(soSendBufferSize);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,7 +151,18 @@ public class UdpInboundChannelAdapterSpec
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec lookupHost(boolean lookupHost) {
|
||||
this.target.setLookupHost(lookupHost);
|
||||
return _this();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the socket.
|
||||
* @param customizer the customizer.
|
||||
* @return the spec.
|
||||
* @since 5.3.3
|
||||
*/
|
||||
public UdpInboundChannelAdapterSpec configureSocket(SocketCustomizer customizer) {
|
||||
this.target.setSocketCustomizer(customizer);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/**
|
||||
* Provides TCP/UDP Component support for the Java DSL.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.integration.ip.dsl;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.ip.udp;
|
||||
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.SocketException;
|
||||
|
||||
/**
|
||||
* Configures a socket.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 5.3.3
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SocketCustomizer {
|
||||
|
||||
/**
|
||||
* Configure the socket ({code setTrafficClass()}, etc).
|
||||
* @param socket the socket.
|
||||
* @throws SocketException a socket exception.
|
||||
*/
|
||||
void configure(DatagramSocket socket) throws SocketException;
|
||||
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A channel adapter to receive incoming UDP packets. Packets can optionally be preceded by a
|
||||
@@ -58,6 +59,7 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
|
||||
|
||||
private int soSendBufferSize = -1;
|
||||
|
||||
private SocketCustomizer socketCustomizer = socket -> { };
|
||||
|
||||
/**
|
||||
* Constructs a UnicastReceivingChannelAdapter that listens on the specified port.
|
||||
@@ -89,6 +91,16 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
|
||||
this.mapper.setLengthCheck(lengthCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a customizer to further configure the socket after creation.
|
||||
* @param socketCustomizer the customizer.
|
||||
* @since 5.3.3
|
||||
*/
|
||||
public void setSocketCustomizer(SocketCustomizer socketCustomizer) {
|
||||
Assert.notNull(socketCustomizer, "'socketCustomizer' cannot be null");
|
||||
this.socketCustomizer = socketCustomizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLongLived() {
|
||||
return true;
|
||||
@@ -169,6 +181,7 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
|
||||
if (this.soSendBufferSize > 0) {
|
||||
out.setSendBufferSize(this.soSendBufferSize);
|
||||
}
|
||||
this.socketCustomizer.configure(out);
|
||||
out.send(ackPack);
|
||||
out.close();
|
||||
}
|
||||
@@ -258,7 +271,7 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets timeout and receive buffer size
|
||||
* Sets timeout and receive buffer size; calls the socket customizer.
|
||||
*
|
||||
* @param socket The socket.
|
||||
* @throws SocketException Any socket exception.
|
||||
@@ -269,6 +282,7 @@ public class UnicastReceivingChannelAdapter extends AbstractInternetProtocolRece
|
||||
if (soReceiveBufferSize > 0) {
|
||||
socket.setReceiveBufferSize(soReceiveBufferSize);
|
||||
}
|
||||
this.socketCustomizer.configure(socket);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -101,6 +101,8 @@ public class UnicastSendingMessageHandler extends
|
||||
|
||||
private EvaluationContext evaluationContext;
|
||||
|
||||
private SocketCustomizer socketCustomizer = socket -> { };
|
||||
|
||||
private volatile CountDownLatch ackLatch;
|
||||
|
||||
private volatile boolean ackThreadRunning;
|
||||
@@ -206,6 +208,25 @@ public class UnicastSendingMessageHandler extends
|
||||
ackTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lengthCheck if true, a four byte binary length header is added to the
|
||||
* packet, allowing the receiver to check for data truncation.
|
||||
* @since 5.0
|
||||
*/
|
||||
public void setLengthCheck(boolean lengthCheck) {
|
||||
this.mapper.setLengthCheck(lengthCheck);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a customizer to further configure the socket after creation.
|
||||
* @param socketCustomizer the customizer.
|
||||
* @since 5.3.3
|
||||
*/
|
||||
public void setSocketCustomizer(SocketCustomizer socketCustomizer) {
|
||||
Assert.notNull(socketCustomizer, "'socketCustomizer' cannot be null");
|
||||
this.socketCustomizer = socketCustomizer;
|
||||
}
|
||||
|
||||
protected final void setReliabilityAttributes(boolean lengthCheck,
|
||||
boolean acknowledge, String ackHost, int ackPort, int ackTimeout) {
|
||||
|
||||
@@ -224,15 +245,6 @@ public class UnicastSendingMessageHandler extends
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lengthCheck if true, a four byte binary length header is added to the
|
||||
* packet, allowing the receiver to check for data truncation.
|
||||
* @since 5.0
|
||||
*/
|
||||
public void setLengthCheck(boolean lengthCheck) {
|
||||
this.mapper.setLengthCheck(lengthCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStart() {
|
||||
if (this.acknowledge) {
|
||||
@@ -495,6 +507,7 @@ public class UnicastSendingMessageHandler extends
|
||||
if (soSendBufferSize > 0) {
|
||||
socket.setSendBufferSize(soSendBufferSize);
|
||||
}
|
||||
this.socketCustomizer.configure(socket);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -873,6 +873,18 @@
|
||||
<xsd:extension base="common-attributes">
|
||||
<xsd:attribute name="check-length" type="xsd:string"/>
|
||||
<xsd:attribute name="multicast" type="xsd:string"/>
|
||||
<xsd:attribute name="socket-customizer" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
A SocketCustomizer bean.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.ip.udp.SocketCustomizer"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
<task:executor id="externalTE" pool-size="10"/>
|
||||
|
||||
<bean id="udpCust" class = "org.springframework.integration.ip.config.ParserUnitTests$SocketCust"/>
|
||||
|
||||
<ip:udp-inbound-channel-adapter id="testInUdp"
|
||||
channel="udpChannel"
|
||||
check-length="true"
|
||||
@@ -35,6 +37,7 @@
|
||||
lookup-host="false"
|
||||
auto-startup="false"
|
||||
phase="1234"
|
||||
socket-customizer="udpCust"
|
||||
/>
|
||||
|
||||
<ip:udp-inbound-channel-adapter id="testInUdpMulticast"
|
||||
@@ -141,6 +144,7 @@
|
||||
local-address="127.0.0.1"
|
||||
task-executor="externalTE"
|
||||
order="23"
|
||||
socket-customizer="udpCust"
|
||||
/>
|
||||
|
||||
<ip:udp-outbound-channel-adapter id="testOutUdpiMulticast"
|
||||
|
||||
@@ -20,6 +20,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.SocketException;
|
||||
import java.time.Duration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
@@ -66,6 +68,7 @@ import org.springframework.integration.ip.tcp.connection.TcpSocketSupport;
|
||||
import org.springframework.integration.ip.udp.DatagramPacketMessageMapper;
|
||||
import org.springframework.integration.ip.udp.MulticastReceivingChannelAdapter;
|
||||
import org.springframework.integration.ip.udp.MulticastSendingMessageHandler;
|
||||
import org.springframework.integration.ip.udp.SocketCustomizer;
|
||||
import org.springframework.integration.ip.udp.UnicastReceivingChannelAdapter;
|
||||
import org.springframework.integration.ip.udp.UnicastSendingMessageHandler;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
@@ -273,6 +276,9 @@ public class ParserUnitTests {
|
||||
@Autowired
|
||||
TcpMessageMapper mapper;
|
||||
|
||||
@Autowired
|
||||
SocketCust socketCustomizer;
|
||||
|
||||
private static CountDownLatch adviceCalled = new CountDownLatch(1);
|
||||
|
||||
@Test
|
||||
@@ -293,6 +299,7 @@ public class ParserUnitTests {
|
||||
assertThat((Boolean) mapperAccessor.getPropertyValue("lookupHost")).isFalse();
|
||||
assertThat(TestUtils.getPropertyValue(udpIn, "autoStartup", Boolean.class)).isFalse();
|
||||
assertThat(dfa.getPropertyValue("phase")).isEqualTo(1234);
|
||||
assertThat(dfa.getPropertyValue("socketCustomizer")).isSameAs(this.socketCustomizer);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -365,6 +372,7 @@ public class ParserUnitTests {
|
||||
assertThat(dfa.getPropertyValue("order")).isEqualTo(23);
|
||||
assertThat(udpOut.getComponentName()).isEqualTo("testOutUdp");
|
||||
assertThat(udpOut.getComponentType()).isEqualTo("ip:udp-outbound-channel-adapter");
|
||||
assertThat(dfa.getPropertyValue("socketCustomizer")).isSameAs(this.socketCustomizer);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -697,4 +705,12 @@ public class ParserUnitTests {
|
||||
|
||||
}
|
||||
|
||||
public static class SocketCust implements SocketCustomizer {
|
||||
|
||||
@Override
|
||||
public void configure(DatagramSocket socket) throws SocketException {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.ip.dsl;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.net.DatagramSocket;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -56,6 +57,7 @@ import org.springframework.integration.ip.tcp.serializer.TcpCodecs;
|
||||
import org.springframework.integration.ip.udp.MulticastSendingMessageHandler;
|
||||
import org.springframework.integration.ip.udp.UdpServerListeningEvent;
|
||||
import org.springframework.integration.ip.udp.UnicastReceivingChannelAdapter;
|
||||
import org.springframework.integration.ip.udp.UnicastSendingMessageHandler;
|
||||
import org.springframework.integration.ip.util.TestingUtilities;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
@@ -100,6 +102,9 @@ public class IpIntegrationTests {
|
||||
@Autowired
|
||||
private UnicastReceivingChannelAdapter udpInbound;
|
||||
|
||||
@Autowired
|
||||
private UnicastSendingMessageHandler udpOutbound;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel udpIn;
|
||||
|
||||
@@ -176,6 +181,8 @@ public class IpIntegrationTests {
|
||||
Message<?> received = this.udpIn.receive(10000);
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(Transformers.objectToString().transform(received).getPayload()).isEqualTo("foo");
|
||||
assertThat(TestUtils.getPropertyValue(this.udpOutbound, "socket", DatagramSocket.class).getTrafficClass())
|
||||
.isEqualTo(0x10);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -303,7 +310,8 @@ public class IpIntegrationTests {
|
||||
|
||||
@Bean
|
||||
public IntegrationFlow outUdpAdapter() {
|
||||
return f -> f.handle(Udp.outboundAdapter(m -> m.getHeaders().get("udp_dest")));
|
||||
return f -> f.handle(Udp.outboundAdapter(m -> m.getHeaders().get("udp_dest"))
|
||||
.configureSocket(socket -> socket.setTrafficClass(0x10)));
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -72,6 +72,7 @@ The following example configures a UDP outbound channel adapter:
|
||||
host="somehost"
|
||||
port="11111"
|
||||
multicast="false"
|
||||
socket-customizer="udpCustomizer"
|
||||
channel="exampleChannel"/>
|
||||
----
|
||||
====
|
||||
@@ -88,7 +89,9 @@ The `length` header provides a mechanism to detect this.
|
||||
Starting with version 4.3, you can set the `port` to `0`, in which case the operating system chooses the port.
|
||||
The chosen port can be discovered by invoking `getPort()` after the adapter is started and `isListening()` returns `true`.
|
||||
|
||||
The preceding example shows an outbound channel adapter that adds length checking to the datagram packets:
|
||||
Starting with version 5.3.3, you can add a `SocketCustomizer` bean to modify the `DatagramSocket` after it is created (for example, call `setTrafficClass(0x10)`).
|
||||
|
||||
The following example shows an outbound channel adapter that adds length checking to the datagram packets:
|
||||
|
||||
====
|
||||
[source,xml]
|
||||
@@ -143,7 +146,7 @@ The following example shows how to configure an outbound UDP adapter with Java:
|
||||
@Bean
|
||||
@ServiceActivator(inputChannel = "udpOut")
|
||||
public UnicastSendingMessageHandler handler() {
|
||||
return new UnicastSendingMessageHandler("localhost", 11111);
|
||||
return new UnicastSendingMessageHandler("localhost", 11111);
|
||||
}
|
||||
----
|
||||
====
|
||||
@@ -159,9 +162,9 @@ The following example shows how to configure an outbound UDP adapter with the Ja
|
||||
----
|
||||
@Bean
|
||||
public IntegrationFlow udpOutFlow() {
|
||||
return IntegrationFlows.from("udpOut")
|
||||
.handle(Udp.outboundAdapter("localhost", 1234))
|
||||
.get();
|
||||
return f -> f.handle(Udp.outboundAdapter("localhost", 1234)
|
||||
.configureSocket(socket -> socket.setTrafficClass(0x10)))
|
||||
.get();
|
||||
}
|
||||
----
|
||||
====
|
||||
@@ -178,6 +181,7 @@ The following example shows how to configure a basic unicast inbound udp channel
|
||||
port="11111"
|
||||
receive-buffer-size="500"
|
||||
multicast="false"
|
||||
socket-customizer="udpCustomizer"
|
||||
check-length="true"/>
|
||||
----
|
||||
====
|
||||
@@ -201,6 +205,9 @@ By default, reverse DNS lookups are done on inbound packets to convert IP addres
|
||||
In environments where DNS is not configured, this can cause delays.
|
||||
You can override this default behavior by setting the `lookup-host` attribute to `false`.
|
||||
|
||||
Starting with version 5.3.3, you can add a `SocketCustomizer` bean to modify the `DatagramSocket` after it is created.
|
||||
It is called for the receiving socket and any sockets created for sending acks.
|
||||
|
||||
==== Inbound UDP Adapters (Java Configuration)
|
||||
|
||||
The following example shows how to configure an inbound UDP adapter with Java:
|
||||
@@ -209,9 +216,9 @@ The following example shows how to configure an inbound UDP adapter with Java:
|
||||
----
|
||||
@Bean
|
||||
public UnicastReceivingChannelAdapter udpIn() {
|
||||
UnicastReceivingChannelAdapter adapter = new UnicastReceivingChannelAdapter(11111);
|
||||
adapter.setOutputChannelName("udpChannel");
|
||||
return adapter;
|
||||
UnicastReceivingChannelAdapter adapter = new UnicastReceivingChannelAdapter(11111);
|
||||
adapter.setOutputChannelName("udpChannel");
|
||||
return adapter;
|
||||
}
|
||||
----
|
||||
|
||||
@@ -223,9 +230,9 @@ The following example shows how to configure an inbound UDP adapter with the Jav
|
||||
----
|
||||
@Bean
|
||||
public IntegrationFlow udpIn() {
|
||||
return IntegrationFlows.from(Udp.inboundAdapter(11111))
|
||||
.channel("udpChannel")
|
||||
.get();
|
||||
return IntegrationFlows.from(Udp.inboundAdapter(11111))
|
||||
.channel("udpChannel")
|
||||
.get();
|
||||
}
|
||||
----
|
||||
|
||||
@@ -278,11 +285,11 @@ The following example shows the equivalent configuration with the Java DSL:
|
||||
----
|
||||
@Bean
|
||||
public IntegrationFlow udpEchoUpcaseServer() {
|
||||
return IntegrationFlows.from(Udp.inboundAdapter(11111).id("udpIn"))
|
||||
.<byte[], String>transform(p -> new String(p).toUpperCase())
|
||||
.handle(Udp.outboundAdapter("headers['ip_packetAddress']")
|
||||
.socketExpression("@udpIn.socket"))
|
||||
.get();
|
||||
return IntegrationFlows.from(Udp.inboundAdapter(11111).id("udpIn"))
|
||||
.<byte[], String>transform(p -> new String(p).toUpperCase())
|
||||
.handle(Udp.outboundAdapter("headers['ip_packetAddress']")
|
||||
.socketExpression("@udpIn.socket"))
|
||||
.get();
|
||||
}
|
||||
----
|
||||
====
|
||||
@@ -1396,10 +1403,10 @@ The following listing shows the definition of the `TcpNetConnectionSupport` stra
|
||||
----
|
||||
public interface TcpNetConnectionSupport {
|
||||
|
||||
TcpNetConnection createNewConnection(Socket socket,
|
||||
boolean server, boolean lookupHost,
|
||||
ApplicationEventPublisher applicationEventPublisher,
|
||||
String connectionFactoryName) throws Exception;
|
||||
TcpNetConnection createNewConnection(Socket socket,
|
||||
boolean server, boolean lookupHost,
|
||||
ApplicationEventPublisher applicationEventPublisher,
|
||||
String connectionFactoryName) throws Exception;
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
@@ -67,13 +67,16 @@ The legacy metrics that were replaced by Micrometer meters have been removed.
|
||||
The <<./barrier.adoc#barrier,Thread Barrier>> has now two separate timeout options: `requestTimeout` and `triggerTimeout`.
|
||||
|
||||
[[x5.4-tcp]]
|
||||
=== TCP Changes
|
||||
=== TCP/UDP Changes
|
||||
|
||||
Connection factories now support multiple sending components (`TcpSender`); they remain limited to one receiving component (`TcpListener`).
|
||||
This allows, for example, an inbound gateway and outbound channel adapter to share the same factory, supporting both request/reply and arbitrary messaging from the server to the client.
|
||||
Shared factories should not be used with outbound gateways, unless single-use connections or the `ThreadAffinityClientConnectionFactory` are being used.
|
||||
See <<./ip.adoc#ip-collaborating-adapters,Collaborating Channel Adapters>> and <<./ip.adoc#tcp-gateways, TCP Gateways>> for more information.
|
||||
|
||||
The UDP channel adapters can now be configured with a `SocketCustomizer` which allows the setting of socket properties that are not directly supported by the adapters.
|
||||
See <<./ip.adoc#udp-adapters,UDP Adapters>> for more information.
|
||||
|
||||
[[x5.4-rmi]]
|
||||
=== RMI Changes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user