From 594aba9ddd380c22cf415b1f0bf5d3ff8ca07027 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Thu, 12 Feb 2015 16:44:16 -0500 Subject: [PATCH] Fix Race Condition in Test Interceptor (TCP) The HelloWorldInterceptor (server side) set the negotiated flag after sending the handshake back. The next message could be received before the flag was set and caused the test to fail. Synchronize the server-side handshaking code so that we don't start processing the next message before the negotiated flag is set. Leave the diagnostic log settings in place for now. --- .../tcp/connection/HelloWorldInterceptor.java | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java index bb019faed4..a1a1528b5a 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java @@ -61,36 +61,45 @@ public class HelloWorldInterceptor extends TcpConnectionInterceptorSupport { @Override public boolean onMessage(Message message) { if (!this.negotiated) { - Object payload = message.getPayload(); - if (this.isServer()) { - if (payload.equals(hello)) { - try { - logger.debug(this.toString() + " sending " + this.world); - super.send(MessageBuilder.withPayload(world).build()); - this.negotiated = true; - return true; - } catch (Exception e) { - throw new MessagingException("Negotiation error", e); + synchronized(this) { + if (!this.negotiated) { + Object payload = message.getPayload(); + logger.debug(this.toString() + " received " + payload); + if (this.isServer()) { + if (payload.equals(hello)) { + try { + logger.debug(this.toString() + " sending " + this.world); + super.send(MessageBuilder.withPayload(world).build()); + this.negotiated = true; + return true; + } + catch (Exception e) { + throw new MessagingException("Negotiation error", e); + } + } + else { + throw new MessagingException("Negotiation error, expected '" + hello + + "' received '" + payload + "'"); + } + } + else { + if (payload.equals(world)) { + this.negotiated = true; + this.negotiationSemaphore.release(); + } + else { + throw new MessagingException("Negotiation error - expected '" + world + + "' received " + payload); + } + return true; } - } else { - throw new MessagingException("Negotiation error, expected '" + hello + - "' received '" + payload + "'"); } - } else { - logger.debug(this.toString() + " received " + payload); - if (payload.equals(world)) { - this.negotiated = true; - this.negotiationSemaphore.release(); - } else { - throw new MessagingException("Negotiation error - expected '" + world + - "' received " + payload); - } - return true; } } try { return super.onMessage(message); - } finally { + } + finally { // on the server side, we don't want to close if we are expecting a response if (!(this.isServer() && this.hasRealSender()) && !this.pendingSend) { this.checkDeferredClose(); @@ -113,7 +122,8 @@ public class HelloWorldInterceptor extends TcpConnectionInterceptorSupport { } } super.send(message); - } finally { + } + finally { this.pendingSend = false; this.checkDeferredClose(); }