1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.messaging.support;
18
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.concurrent.atomic.AtomicBoolean;
22 import java.util.concurrent.atomic.AtomicInteger;
23
24 import org.junit.Before;
25 import org.junit.Test;
26
27 import org.springframework.messaging.Message;
28 import org.springframework.messaging.MessageChannel;
29 import org.springframework.messaging.MessageHandler;
30 import org.springframework.messaging.MessagingException;
31
32 import static org.junit.Assert.*;
33 import static org.mockito.Mockito.*;
34
35
36
37
38
39
40 public class ChannelInterceptorTests {
41
42 private ExecutorSubscribableChannel channel;
43
44 private TestMessageHandler messageHandler;
45
46
47 @Before
48 public void setup() {
49 this.channel = new ExecutorSubscribableChannel();
50 this.messageHandler = new TestMessageHandler();
51 this.channel.subscribe(this.messageHandler);
52 }
53
54
55 @Test
56 public void preSendInterceptorReturningModifiedMessage() {
57 Message<?> expected = mock(Message.class);
58 PreSendInterceptor interceptor = new PreSendInterceptor();
59 interceptor.setMessageToReturn(expected);
60 this.channel.addInterceptor(interceptor);
61 this.channel.send(MessageBuilder.withPayload("test").build());
62
63 assertEquals(1, this.messageHandler.getMessages().size());
64 Message<?> result = this.messageHandler.getMessages().get(0);
65
66 assertNotNull(result);
67 assertSame(expected, result);
68 assertTrue(interceptor.wasAfterCompletionInvoked());
69 }
70
71 @Test
72 public void preSendInterceptorReturningNull() {
73 PreSendInterceptor interceptor1 = new PreSendInterceptor();
74 NullReturningPreSendInterceptor interceptor2 = new NullReturningPreSendInterceptor();
75 this.channel.addInterceptor(interceptor1);
76 this.channel.addInterceptor(interceptor2);
77 Message<?> message = MessageBuilder.withPayload("test").build();
78 this.channel.send(message);
79
80 assertEquals(1, interceptor1.getCounter().get());
81 assertEquals(1, interceptor2.getCounter().get());
82 assertEquals(0, this.messageHandler.getMessages().size());
83 assertTrue(interceptor1.wasAfterCompletionInvoked());
84 assertFalse(interceptor2.wasAfterCompletionInvoked());
85 }
86
87 @Test
88 public void postSendInterceptorMessageWasSent() {
89 final AtomicBoolean preSendInvoked = new AtomicBoolean(false);
90 final AtomicBoolean completionInvoked = new AtomicBoolean(false);
91 this.channel.addInterceptor(new ChannelInterceptorAdapter() {
92 @Override
93 public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
94 assertInput(message, channel, sent);
95 preSendInvoked.set(true);
96 }
97 @Override
98 public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, Exception ex) {
99 assertInput(message, channel, sent);
100 completionInvoked.set(true);
101 }
102 private void assertInput(Message<?> message, MessageChannel channel, boolean sent) {
103 assertNotNull(message);
104 assertNotNull(channel);
105 assertSame(ChannelInterceptorTests.this.channel, channel);
106 assertTrue(sent);
107 }
108 });
109 this.channel.send(MessageBuilder.withPayload("test").build());
110 assertTrue(preSendInvoked.get());
111 assertTrue(completionInvoked.get());
112 }
113
114 @Test
115 public void postSendInterceptorMessageWasNotSent() {
116 final AbstractMessageChannel testChannel = new AbstractMessageChannel() {
117 @Override
118 protected boolean sendInternal(Message<?> message, long timeout) {
119 return false;
120 }
121 };
122 final AtomicBoolean preSendInvoked = new AtomicBoolean(false);
123 final AtomicBoolean completionInvoked = new AtomicBoolean(false);
124 testChannel.addInterceptor(new ChannelInterceptorAdapter() {
125 @Override
126 public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
127 assertInput(message, channel, sent);
128 preSendInvoked.set(true);
129 }
130 @Override
131 public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, Exception ex) {
132 assertInput(message, channel, sent);
133 completionInvoked.set(true);
134 }
135 private void assertInput(Message<?> message, MessageChannel channel, boolean sent) {
136 assertNotNull(message);
137 assertNotNull(channel);
138 assertSame(testChannel, channel);
139 assertFalse(sent);
140 }
141 });
142 testChannel.send(MessageBuilder.withPayload("test").build());
143 assertTrue(preSendInvoked.get());
144 assertTrue(completionInvoked.get());
145 }
146
147 @Test
148 public void afterCompletionWithSendException() {
149 final AbstractMessageChannel testChannel = new AbstractMessageChannel() {
150 @Override
151 protected boolean sendInternal(Message<?> message, long timeout) {
152 throw new RuntimeException("Simulated exception");
153 }
154 };
155 PreSendInterceptor interceptor1 = new PreSendInterceptor();
156 PreSendInterceptor interceptor2 = new PreSendInterceptor();
157 testChannel.addInterceptor(interceptor1);
158 testChannel.addInterceptor(interceptor2);
159 try {
160 testChannel.send(MessageBuilder.withPayload("test").build());
161 }
162 catch (Exception ex) {
163 assertEquals("Simulated exception", ex.getCause().getMessage());
164 }
165 assertTrue(interceptor1.wasAfterCompletionInvoked());
166 assertTrue(interceptor2.wasAfterCompletionInvoked());
167 }
168
169 @Test
170 public void afterCompletionWithPreSendException() {
171 PreSendInterceptor interceptor1 = new PreSendInterceptor();
172 PreSendInterceptor interceptor2 = new PreSendInterceptor();
173 interceptor2.setExceptionToRaise(new RuntimeException("Simulated exception"));
174 this.channel.addInterceptor(interceptor1);
175 this.channel.addInterceptor(interceptor2);
176 try {
177 this.channel.send(MessageBuilder.withPayload("test").build());
178 }
179 catch (Exception ex) {
180 assertEquals("Simulated exception", ex.getCause().getMessage());
181 }
182 assertTrue(interceptor1.wasAfterCompletionInvoked());
183 assertFalse(interceptor2.wasAfterCompletionInvoked());
184 }
185
186
187 private static class TestMessageHandler implements MessageHandler {
188
189 private final List<Message<?>> messages = new ArrayList<Message<?>>();
190
191 public List<Message<?>> getMessages() {
192 return this.messages;
193 }
194
195 @Override
196 public void handleMessage(Message<?> message) throws MessagingException {
197 this.messages.add(message);
198 }
199 }
200
201
202 private abstract static class AbstractTestInterceptor extends ChannelInterceptorAdapter {
203
204 private AtomicInteger counter = new AtomicInteger();
205
206 private volatile boolean afterCompletionInvoked;
207
208 public AtomicInteger getCounter() {
209 return this.counter;
210 }
211
212 public boolean wasAfterCompletionInvoked() {
213 return this.afterCompletionInvoked;
214 }
215
216 @Override
217 public Message<?> preSend(Message<?> message, MessageChannel channel) {
218 assertNotNull(message);
219 counter.incrementAndGet();
220 return message;
221 }
222
223 @Override
224 public void afterSendCompletion(Message<?> message, MessageChannel channel, boolean sent, Exception ex) {
225 this.afterCompletionInvoked = true;
226 }
227 }
228
229
230 private static class PreSendInterceptor extends AbstractTestInterceptor {
231
232 private Message<?> messageToReturn;
233
234 private RuntimeException exceptionToRaise;
235
236 public void setMessageToReturn(Message<?> messageToReturn) {
237 this.messageToReturn = messageToReturn;
238 }
239
240 public void setExceptionToRaise(RuntimeException exception) {
241 this.exceptionToRaise = exception;
242 }
243
244 @Override
245 public Message<?> preSend(Message<?> message, MessageChannel channel) {
246 super.preSend(message, channel);
247 if (this.exceptionToRaise != null) {
248 throw this.exceptionToRaise;
249 }
250 return (this.messageToReturn != null ? this.messageToReturn : message);
251 }
252 }
253
254
255 private static class NullReturningPreSendInterceptor extends AbstractTestInterceptor {
256
257 @Override
258 public Message<?> preSend(Message<?> message, MessageChannel channel) {
259 super.preSend(message, channel);
260 return null;
261 }
262 }
263
264 }