/*
* 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.ws.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.endpoint.PollingConsumer;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.integration.mapping.AbstractHeaderMapper;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.ws.MarshallingWebServiceOutboundGateway;
import org.springframework.integration.ws.SimpleWebServiceOutboundGateway;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.client.core.FaultMessageResolver;
import org.springframework.ws.client.core.SourceExtractor;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceMessageExtractor;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
import org.springframework.ws.transport.WebServiceMessageSender;
/**
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gunnar Hillert
* @author Gary Russell
* @author Artem Bilan
*/
@RunWith(SpringRunner.class)
public class WebServiceOutboundGatewayParserTests {
private static volatile int adviceCalled;
@Autowired
private ApplicationContext context;
@Test
public void simpleGatewayWithReplyChannel() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithReplyChannel", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
Object expected = this.context.getBean("outputChannel");
assertEquals(expected, accessor.getPropertyValue("outputChannel"));
Assert.assertEquals(Boolean.FALSE, accessor.getPropertyValue("requiresReply"));
AbstractHeaderMapper.HeaderMatcher requestHeaderMatcher = TestUtils.getPropertyValue(endpoint,
"handler.headerMapper.requestHeaderMatcher", AbstractHeaderMapper.HeaderMatcher.class);
assertTrue(requestHeaderMatcher.matchHeader("testRequest"));
assertFalse(requestHeaderMatcher.matchHeader("testReply"));
AbstractHeaderMapper.HeaderMatcher replyHeaderMatcher = TestUtils.getPropertyValue(endpoint,
"handler.headerMapper.replyHeaderMatcher", AbstractHeaderMapper.HeaderMatcher.class);
assertFalse(replyHeaderMatcher.matchHeader("testRequest"));
assertTrue(replyHeaderMatcher.matchHeader("testReply"));
Long sendTimeout = TestUtils.getPropertyValue(gateway, "messagingTemplate.sendTimeout", Long.class);
assertEquals(Long.valueOf(777), sendTimeout);
assertSame(this.context.getBean("webServiceTemplate"),
TestUtils.getPropertyValue(gateway, "webServiceTemplate"));
}
@Test
public void simpleGatewayWithIgnoreEmptyResponseTrueByDefault() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithReplyChannel", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
assertEquals(Boolean.TRUE, accessor.getPropertyValue("ignoreEmptyResponses"));
Assert.assertEquals(Boolean.FALSE, accessor.getPropertyValue("requiresReply"));
}
@Test
public void simpleGatewayWithIgnoreEmptyResponses() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithIgnoreEmptyResponsesFalseAndRequiresReplyTrue",
AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
assertEquals(Boolean.FALSE, accessor.getPropertyValue("ignoreEmptyResponses"));
assertEquals(Boolean.TRUE, accessor.getPropertyValue("requiresReply"));
assertEquals(Boolean.FALSE, accessor.getPropertyValue("extractPayload"));
}
@Test
public void simpleGatewayWithDefaultSourceExtractor() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithDefaultSourceExtractor", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
assertEquals("DefaultSourceExtractor", accessor.getPropertyValue("sourceExtractor").getClass().getSimpleName());
}
@Test
public void simpleGatewayWithCustomSourceExtractor() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomSourceExtractor", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
SourceExtractor<?> sourceExtractor = (SourceExtractor<?>) context.getBean("sourceExtractor");
assertEquals(sourceExtractor, accessor.getPropertyValue("sourceExtractor"));
}
@Test
public void simpleGatewayWithCustomRequestCallback() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomRequestCallback", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
WebServiceMessageCallback callback = (WebServiceMessageCallback) context.getBean("requestCallback");
assertEquals(callback, accessor.getPropertyValue("requestCallback"));
}
@Test
public void simpleGatewayWithCustomMessageFactory() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomMessageFactory", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
accessor = new DirectFieldAccessor(accessor.getPropertyValue("webServiceTemplate"));
WebServiceMessageFactory factory = (WebServiceMessageFactory) context.getBean("messageFactory");
assertEquals(factory, accessor.getPropertyValue("messageFactory"));
}
@Test
public void simpleGatewayWithCustomSourceExtractorAndMessageFactory() {
AbstractEndpoint endpoint = context.getBean("gatewayWithCustomSourceExtractorAndMessageFactory", AbstractEndpoint.class);
SourceExtractor<?> sourceExtractor = (SourceExtractor<?>) context.getBean("sourceExtractor");
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
assertEquals(sourceExtractor, accessor.getPropertyValue("sourceExtractor"));
accessor = new DirectFieldAccessor(accessor.getPropertyValue("webServiceTemplate"));
WebServiceMessageFactory factory = (WebServiceMessageFactory) context.getBean("messageFactory");
assertEquals(factory, accessor.getPropertyValue("messageFactory"));
}
@Test
public void simpleGatewayWithCustomFaultMessageResolver() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomFaultMessageResolver", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
accessor = new DirectFieldAccessor(accessor.getPropertyValue("webServiceTemplate"));
FaultMessageResolver resolver = (FaultMessageResolver) context.getBean("faultMessageResolver");
assertEquals(resolver, accessor.getPropertyValue("faultMessageResolver"));
}
@Test
public void simpleGatewayWithCustomMessageSender() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomMessageSender", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
accessor = new DirectFieldAccessor(accessor.getPropertyValue("webServiceTemplate"));
WebServiceMessageSender messageSender = (WebServiceMessageSender) context.getBean("messageSender");
assertEquals(messageSender, ((WebServiceMessageSender[]) accessor.getPropertyValue("messageSenders"))[0]);
}
@Test
public void simpleGatewayWithCustomMessageSenderList() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomMessageSenderList", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
accessor = new DirectFieldAccessor(accessor.getPropertyValue("webServiceTemplate"));
WebServiceMessageSender messageSender = (WebServiceMessageSender) context.getBean("messageSender");
assertEquals(messageSender, ((WebServiceMessageSender[]) accessor.getPropertyValue("messageSenders"))[0]);
assertEquals("Wrong number of message senders ",
2, ((WebServiceMessageSender[]) accessor.getPropertyValue("messageSenders")).length);
}
@Test
public void simpleGatewayWithCustomInterceptor() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomInterceptor", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
accessor = new DirectFieldAccessor(accessor.getPropertyValue("webServiceTemplate"));
ClientInterceptor interceptor = context.getBean("interceptor", ClientInterceptor.class);
assertEquals(interceptor, ((ClientInterceptor[]) accessor.getPropertyValue("interceptors"))[0]);
}
@Test
public void simpleGatewayWithCustomInterceptorList() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithCustomInterceptorList", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
accessor = new DirectFieldAccessor(accessor.getPropertyValue("webServiceTemplate"));
ClientInterceptor interceptor = context.getBean("interceptor", ClientInterceptor.class);
assertEquals(interceptor, ((ClientInterceptor[]) accessor.getPropertyValue("interceptors"))[0]);
assertEquals("Wrong number of interceptors ",
2, ((ClientInterceptor[]) accessor.getPropertyValue("interceptors")).length);
}
@Test
public void simpleGatewayWithPoller() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithPoller", AbstractEndpoint.class);
assertEquals(PollingConsumer.class, endpoint.getClass());
Object triggerObject = new DirectFieldAccessor(endpoint).getPropertyValue("trigger");
assertEquals(PeriodicTrigger.class, triggerObject.getClass());
PeriodicTrigger trigger = (PeriodicTrigger) triggerObject;
DirectFieldAccessor accessor = new DirectFieldAccessor(trigger);
assertEquals("PeriodicTrigger had wrong period",
5000, ((Long) accessor.getPropertyValue("period")).longValue());
}
@Test
public void simpleGatewayWithOrder() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithOrderAndAutoStartupFalse", AbstractEndpoint.class);
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
assertEquals(99, new DirectFieldAccessor(gateway).getPropertyValue("order"));
}
@Test
public void simpleGatewayWithStartupFalse() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithOrderAndAutoStartupFalse", AbstractEndpoint.class);
assertEquals(Boolean.FALSE, new DirectFieldAccessor(endpoint).getPropertyValue("autoStartup"));
}
@Test
public void marshallingGatewayWithAllInOneMarshaller() {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"marshallingWebServiceOutboundGatewayParserTests.xml", this.getClass());
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithAllInOneMarshaller");
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = TestUtils.getPropertyValue(endpoint, "handler");
Marshaller marshaller = context.getBean("marshallerAndUnmarshaller", Marshaller.class);
assertSame(marshaller, TestUtils.getPropertyValue(gateway, "webServiceTemplate.marshaller", Marshaller.class));
assertSame(marshaller, TestUtils.getPropertyValue(gateway, "webServiceTemplate.unmarshaller", Unmarshaller.class));
context.close();
}
@Test
public void marshallingGatewayWithSeparateMarshallerAndUnmarshaller() {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"marshallingWebServiceOutboundGatewayParserTests.xml", this.getClass());
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithSeparateMarshallerAndUnmarshaller");
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = TestUtils.getPropertyValue(endpoint, "handler");
Marshaller marshaller = context.getBean("marshaller", Marshaller.class);
Unmarshaller unmarshaller = context.getBean("unmarshaller", Unmarshaller.class);
assertSame(marshaller, TestUtils.getPropertyValue(gateway, "webServiceTemplate.marshaller", Marshaller.class));
assertSame(unmarshaller, TestUtils.getPropertyValue(gateway, "webServiceTemplate.unmarshaller", Unmarshaller.class));
context.close();
}
@Test
public void marshallingGatewayWithCustomRequestCallback() {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"marshallingWebServiceOutboundGatewayParserTests.xml", this.getClass());
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithCustomRequestCallback");
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = TestUtils.getPropertyValue(endpoint, "handler");
assertEquals(MarshallingWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
WebServiceMessageCallback callback = (WebServiceMessageCallback) context.getBean("requestCallback");
assertEquals(callback, accessor.getPropertyValue("requestCallback"));
context.close();
}
@Test
public void marshallingGatewayWithAllInOneMarshallerAndMessageFactory() {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"marshallingWebServiceOutboundGatewayParserTests.xml", this.getClass());
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithAllInOneMarshallerAndMessageFactory");
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = TestUtils.getPropertyValue(endpoint, "handler");
Marshaller marshaller = context.getBean("marshallerAndUnmarshaller", Marshaller.class);
assertSame(marshaller, TestUtils.getPropertyValue(gateway, "webServiceTemplate.marshaller", Marshaller.class));
assertSame(marshaller, TestUtils.getPropertyValue(gateway, "webServiceTemplate.unmarshaller", Unmarshaller.class));
WebServiceMessageFactory messageFactory = (WebServiceMessageFactory) context.getBean("messageFactory");
assertEquals(messageFactory, TestUtils.getPropertyValue(gateway, "webServiceTemplate.messageFactory"));
context.close();
}
@Test
public void marshallingGatewayWithSeparateMarshallerAndUnmarshallerAndMessageFactory() {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"marshallingWebServiceOutboundGatewayParserTests.xml", this.getClass());
AbstractEndpoint endpoint = (AbstractEndpoint) context.getBean("gatewayWithSeparateMarshallerAndUnmarshallerAndMessageFactory");
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = TestUtils.getPropertyValue(endpoint, "handler");
Marshaller marshaller = context.getBean("marshaller", Marshaller.class);
Unmarshaller unmarshaller = context.getBean("unmarshaller", Unmarshaller.class);
assertSame(marshaller, TestUtils.getPropertyValue(gateway, "webServiceTemplate.marshaller", Marshaller.class));
assertSame(unmarshaller, TestUtils.getPropertyValue(gateway, "webServiceTemplate.unmarshaller", Unmarshaller.class));
WebServiceMessageFactory messageFactory = context.getBean("messageFactory", WebServiceMessageFactory.class);
assertEquals(messageFactory, TestUtils.getPropertyValue(gateway, "webServiceTemplate.messageFactory"));
context.close();
}
@Test
public void simpleGatewayWithDestinationProvider() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithDestinationProvider", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
Object gateway = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
StubDestinationProvider stubProvider = (StubDestinationProvider) context.getBean("destinationProvider");
assertEquals(SimpleWebServiceOutboundGateway.class, gateway.getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(gateway);
assertEquals("Wrong DestinationProvider", stubProvider, accessor.getPropertyValue("destinationProvider"));
assertNull(accessor.getPropertyValue("uri"));
Object destinationProviderObject = new DirectFieldAccessor(
accessor.getPropertyValue("webServiceTemplate")).getPropertyValue("destinationProvider");
assertEquals("Wrong DestinationProvider", stubProvider, destinationProviderObject);
}
@Test
public void advised() {
adviceCalled = 0;
AbstractEndpoint endpoint = this.context.getBean("gatewayWithAdvice", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
MessageHandler handler = TestUtils.getPropertyValue(endpoint, "handler", MessageHandler.class);
handler.handleMessage(new GenericMessage<String>("foo"));
assertEquals(1, adviceCalled);
}
@Test
public void testInt2718AdvisedInsideAChain() {
adviceCalled = 0;
MessageChannel channel = context.getBean("gatewayWithAdviceInsideAChain", MessageChannel.class);
channel.send(new GenericMessage<String>("foo"));
assertEquals(1, adviceCalled);
}
@Test
@SuppressWarnings("unchecked")
public void jmsUri() {
AbstractEndpoint endpoint = this.context.getBean("gatewayWithJmsUri", AbstractEndpoint.class);
assertEquals(EventDrivenConsumer.class, endpoint.getClass());
MessageHandler handler = TestUtils.getPropertyValue(endpoint, "handler", MessageHandler.class);
assertNull(TestUtils.getPropertyValue(handler, "destinationProvider"));
assertFalse(TestUtils.getPropertyValue(handler, "encodeUri", Boolean.class));
WebServiceTemplate webServiceTemplate = TestUtils.getPropertyValue(handler, "webServiceTemplate",
WebServiceTemplate.class);
webServiceTemplate = spy(webServiceTemplate);
doReturn(null).when(webServiceTemplate).sendAndReceive(anyString(),
any(WebServiceMessageCallback.class),
ArgumentMatchers.<WebServiceMessageExtractor<Object>>any());
new DirectFieldAccessor(handler).setPropertyValue("webServiceTemplate", webServiceTemplate);
handler.handleMessage(new GenericMessage<String>("foo"));
verify(webServiceTemplate).sendAndReceive(eq("jms:wsQueue"),
any(WebServiceMessageCallback.class),
ArgumentMatchers.<WebServiceMessageExtractor<Object>>any());
}
@Test(expected = BeanDefinitionParsingException.class)
public void invalidGatewayWithBothUriAndDestinationProvider() {
new ClassPathXmlApplicationContext("invalidGatewayWithBothUriAndDestinationProvider.xml", this.getClass())
.close();
}
@Test(expected = BeanDefinitionParsingException.class)
public void invalidGatewayWithNeitherUriNorDestinationProvider() {
new ClassPathXmlApplicationContext("invalidGatewayWithNeitherUriNorDestinationProvider.xml", this.getClass())
.close();
}
public static class FooAdvice extends AbstractRequestHandlerAdvice {
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
adviceCalled++;
return null;
}
}
}