From b7d64d12da9eafeb9bfa725cf371ffa6e265837c 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 3760daada7..6ced05cf8c 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(); }