/*
* Copyright 2002-2017 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
*
* http://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.jmx;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.handler.MessageProcessor;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.StackTraceUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* See INT-1688 for background.
*
* @author Mark Fisher
* @author Artem Bilan
* @author Gary Russell
* @since 2.0.1
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class ServiceActivatorDefaultFrameworkMethodTests {
@Autowired
private MessageChannel gatewayTestInputChannel;
@Autowired
private MessageChannel replyingHandlerTestInputChannel;
@Autowired
private MessageChannel optimizedRefReplyingHandlerTestInputChannel;
@Autowired
private MessageChannel replyingHandlerWithStandardMethodTestInputChannel;
@Autowired
private MessageChannel replyingHandlerWithOtherMethodTestInputChannel;
@Autowired
private MessageChannel handlerTestInputChannel;
@Autowired
private MessageChannel processorTestInputChannel;
@Autowired
private EventDrivenConsumer processorTestService;
@Autowired
private MessageProcessor<?> testMessageProcessor;
@Test
public void testGateway() {
QueueChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
this.gatewayTestInputChannel.send(message);
Message<?> reply = replyChannel.receive(0);
assertEquals("gatewayTestInputChannel,gatewayTestService,gateway,requestChannel,bridge,replyChannel", reply.getHeaders().get("history").toString());
}
@Test
public void testReplyingMessageHandler() {
QueueChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
this.replyingHandlerTestInputChannel.send(message);
Message<?> reply = replyChannel.receive(0);
assertEquals("TEST", reply.getPayload());
assertEquals("replyingHandlerTestInputChannel,replyingHandlerTestService", reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("AbstractSubscribableChannel", "MethodInvokerHelper", st));
}
@Test
public void testOptimizedReplyingMessageHandler() {
QueueChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
this.optimizedRefReplyingHandlerTestInputChannel.send(message);
Message<?> reply = replyChannel.receive(0);
assertEquals("TEST", reply.getPayload());
assertEquals("optimizedRefReplyingHandlerTestInputChannel,optimizedRefReplyingHandlerTestService",
reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("AbstractSubscribableChannel", "MethodInvokerHelper", st));
}
@Test
public void testReplyingMessageHandlerWithStandardMethod() {
QueueChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
this.replyingHandlerWithStandardMethodTestInputChannel.send(message);
Message<?> reply = replyChannel.receive(0);
assertEquals("TEST", reply.getPayload());
assertEquals("replyingHandlerWithStandardMethodTestInputChannel,replyingHandlerWithStandardMethodTestService", reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("AbstractSubscribableChannel", "MethodInvokerHelper", st));
}
@Test
public void testReplyingMessageHandlerWithOtherMethod() {
QueueChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
this.replyingHandlerWithOtherMethodTestInputChannel.send(message);
Message<?> reply = replyChannel.receive(0);
assertEquals("bar", reply.getPayload());
assertEquals("replyingHandlerWithOtherMethodTestInputChannel,replyingHandlerWithOtherMethodTestService", reply.getHeaders().get("history").toString());
}
@Test
public void testMessageHandler() {
QueueChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
this.handlerTestInputChannel.send(message);
}
// INT-2399
@Test
public void testMessageProcessor() {
Object processor = TestUtils.getPropertyValue(processorTestService, "handler.processor");
assertSame(testMessageProcessor, processor);
QueueChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload("bar").setReplyChannel(replyChannel).build();
this.processorTestInputChannel.send(message);
Message<?> reply = replyChannel.receive(0);
assertEquals("foo:bar", reply.getPayload());
assertEquals("processorTestInputChannel,processorTestService", reply.getHeaders().get("history").toString());
}
@Test
public void testFailOnDoubleReference() {
try {
new ClassPathXmlApplicationContext(this.getClass().getSimpleName() + "-fail-context.xml",
this.getClass()).close();
fail("Expected exception due to 2 endpoints referencing the same bean");
}
catch (Exception e) {
assertThat(e, Matchers.instanceOf(BeanCreationException.class));
assertThat(e.getCause(), Matchers.instanceOf(BeanCreationException.class));
assertThat(e.getCause().getCause(), Matchers.instanceOf(IllegalArgumentException.class));
assertThat(e.getCause().getCause().getMessage(),
Matchers.containsString("An AbstractMessageProducingMessageHandler may only be referenced once"));
}
}
private interface Foo {
String foo(String in);
}
@SuppressWarnings("unused")
private static class TestReplyingMessageHandler extends AbstractReplyProducingMessageHandler implements Foo {
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
Exception e = new RuntimeException();
StackTraceElement[] st = e.getStackTrace();
return MessageBuilder.withPayload(requestMessage.getPayload().toString().toUpperCase())
.setHeader("callStack", st);
}
@Override
public String foo(String in) {
Exception e = new RuntimeException();
StackTraceElement[] st = e.getStackTrace();
// use this to test that StackTraceUtils works as expected and returns false
assertFalse(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("AbstractSubscribableChannel", "MethodInvokerHelper", st));
return "bar";
}
}
@SuppressWarnings("unused")
private static class TestMessageHandler implements MessageHandler {
@Override
public void handleMessage(Message<?> requestMessage) {
Exception e = new RuntimeException();
StackTraceElement[] st = e.getStackTrace();
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("AbstractSubscribableChannel", "MethodInvokerHelper", st));
}
}
@SuppressWarnings("unused")
private static class TestMessageProcessor implements MessageProcessor<String> {
private String prefix;
public void setPrefix(String prefix) {
this.prefix = prefix;
}
@Override
public String processMessage(Message<?> message) {
return prefix + ":" + message.getPayload();
}
}
}