HeaderMapper refactoring

INT-2083
added outbound namespace support for XMPP header mapper

INT-2083
added inbound namespace support for XMPP header mapper

INT-2083
polished XMPP inbound/outbound header mappings, added namespace support for AMQP inbound adapter/gateway header mappings

INT-2083
added support and tests for AMQP outbound gateways and adapters

INT-2083
polishing and adding more tests for AMQP support for header mappings

INT-2083
polishing AMQP and XMPP header mappings, generalized headerMapper configuration in IntegrationNamespaceUtils.configureHeaderMapper(..) method

INT-2803
added headermapping support to WS outbound gateways

INT-2803 polishing

INT-2083
refactored SimpleWebServiceOutboundGateway, added full request/reply test

INT-2083
polished MarshallingWebServiceOutboundGateway to add marshalling callback handlers, added test for marshalling call

INT-2083
polishing based on PR comments

INT-2083 interim commit

INT-2083
added RequestReplyHeaderMapper startegy and migrated AMQP Header Mapper to use it

INT-2083
migrated WS and XMPP to use a new RequestReplyHeaderMapper strategy

INT-2083 polishing with PR comments

INT-2083 polishing
removed introspection method, simplified things

INT-2083 polishing based on recent PR comments

INT-2083 interim commit

INT-2083 polishing WS module

INT-2083
refactored to make sure that Soap action header is set within HeaderMapper

INT-2083 polishing
ensured the Soap header is set to default value if not provided

INT-2083 polishing, putting tests back
This commit is contained in:
Mark Fisher
2011-10-06 10:24:13 -04:00
parent ff7bbfa404
commit adf93e5560
50 changed files with 2330 additions and 500 deletions

View File

@@ -22,9 +22,13 @@
<beans:constructor-arg value="org.jivesoftware.smack.XMPPConnection"/>
</beans:bean>
<channel id="xmppInbound"/>
<channel id="xmppInbound">
<queue/>
</channel>
<xmpp:inbound-channel-adapter id="xmppInboundAdapter" channel="xmppInbound"
xmpp-connection="testConnection" extract-payload="false" auto-startup="false" error-channel="errorChannel"/>
xmpp-connection="testConnection" extract-payload="false"
auto-startup="false" error-channel="errorChannel"
mapped-request-headers="foo*, xmpp*"/>
</beans:beans>

View File

@@ -16,21 +16,29 @@
package org.springframework.integration.xmpp.config;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import java.lang.reflect.Field;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Message;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.xmpp.inbound.ChatMessageListeningEndpoint;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.ReflectionUtils;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
/**
* @author Oleg Zhurakousky
@@ -42,6 +50,9 @@ public class ChatMessageInboundChannelAdapterParserTests {
@Autowired
private ApplicationContext context;
@Autowired
private QueueChannel xmppInbound;
@Test
public void testInboundAdapter(){
@@ -49,10 +60,37 @@ public class ChatMessageInboundChannelAdapterParserTests {
MessageChannel errorChannel = (MessageChannel) TestUtils.getPropertyValue(adapter, "errorChannel");
assertEquals(context.getBean("errorChannel"), errorChannel);
assertFalse(adapter.isAutoStartup());
DirectChannel channel = (DirectChannel) TestUtils.getPropertyValue(adapter, "outputChannel");
QueueChannel channel = (QueueChannel) TestUtils.getPropertyValue(adapter, "outputChannel");
assertEquals("xmppInbound", channel.getComponentName());
XMPPConnection connection = (XMPPConnection)TestUtils.getPropertyValue(adapter, "xmppConnection");
assertEquals(connection, context.getBean("testConnection"));
}
@Test
public void testInboundAdapterUsageWithHeaderMapper() {
XMPPConnection xmppConnection = Mockito.mock(XMPPConnection.class);
ChatManager chatManager = Mockito.mock(ChatManager.class);
Mockito.when(xmppConnection.getChatManager()).thenReturn(chatManager);
Chat chat = Mockito.mock(Chat.class);
Mockito.when(chatManager.getThreadChat(Mockito.any(String.class))).thenReturn(chat);
ChatMessageListeningEndpoint adapter = context.getBean("xmppInboundAdapter", ChatMessageListeningEndpoint.class);
Field xmppConnectionField = ReflectionUtils.findField(ChatMessageListeningEndpoint.class, "xmppConnection");
xmppConnectionField.setAccessible(true);
ReflectionUtils.setField(xmppConnectionField, adapter, xmppConnection);
PacketListener packetListener = TestUtils.getPropertyValue(adapter, "packetListener", PacketListener.class);
Message message = new Message();
message.setBody("hello");
message.setTo("oleg");
message.setProperty("foo", "foo");
message.setProperty("bar", "bar");
packetListener.processPacket(message);
org.springframework.integration.Message<?> siMessage = xmppInbound.receive(0);
assertEquals("foo", siMessage.getHeaders().get("foo"));
assertEquals("oleg", siMessage.getHeaders().get("xmpp_to"));
}
}

View File

@@ -15,21 +15,32 @@
<int-xmpp:outbound-channel-adapter id="outboundEventAdapter"
channel="outboundEventChannel"
xmpp-connection="testConnection"/>
xmpp-connection="testConnection"
mapped-request-headers="foo*, bar*"/>
<int:channel id="outboundPollingChannel">
<int:queue/>
</int:channel>
<int-xmpp:outbound-channel-adapter id="outboundPollingAdapter"
<int-xmpp:outbound-channel-adapter id="pollingConsumer"
channel="outboundPollingChannel"
xmpp-connection="testConnection">
<int:poller fixed-rate="1000" max-messages-per-poll="1"/>
<int:poller fixed-rate="5000" max-messages-per-poll="1"/>
</int-xmpp:outbound-channel-adapter>
<int-xmpp:outbound-channel-adapter id="withHeaderMapper"
channel="outboundPollingChannel"
xmpp-connection="testConnection"
header-mapper="headerMapper">
<int:poller fixed-rate="5000" max-messages-per-poll="1"/>
</int-xmpp:outbound-channel-adapter>
<bean id="headerMapper" class="org.springframework.integration.xmpp.support.DefaultXmppHeaderMapper">
<property name="requestHeaderNames" value="foo*"/>
</bean>
<int-xmpp:outbound-channel-adapter id="outboundNoChannelAdapter"
xmpp-connection="testConnection">
<!-- <int:poller fixed-rate="1000" max-messages-per-poll="1"/>-->
</int-xmpp:outbound-channel-adapter>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -16,15 +16,14 @@
package org.springframework.integration.xmpp.config;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.util.List;
import org.jivesoftware.smack.XMPPConnection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -37,9 +36,16 @@ import org.springframework.integration.endpoint.PollingConsumer;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.xmpp.XmppHeaders;
import org.springframework.integration.xmpp.support.DefaultXmppHeaderMapper;
import org.springframework.integration.xmpp.support.XmppHeaderMapper;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
@@ -50,10 +56,13 @@ public class ChatMessageOutboundChannelAdapterParserTests {
@Autowired
private ApplicationContext context;
@Autowired
private XmppHeaderMapper headerMapper;
@Test
public void testPollingConsumer() {
Object pollingConsumer = context.getBean("outboundPollingAdapter");
Object pollingConsumer = context.getBean("withHeaderMapper");
QueueChannel channel = (QueueChannel) TestUtils.getPropertyValue(pollingConsumer, "inputChannel");
assertEquals("outboundPollingChannel", channel.getComponentName());
assertTrue(pollingConsumer instanceof PollingConsumer);
@@ -65,20 +74,43 @@ public class ChatMessageOutboundChannelAdapterParserTests {
assertTrue(eventConsumer instanceof SubscribableChannel);
}
@SuppressWarnings("unchecked")
@Test
public void testEventConsumer() {
Object eventConsumer = context.getBean("outboundEventAdapter");
DefaultXmppHeaderMapper headerMapper =
TestUtils.getPropertyValue(eventConsumer, "handler.headerMapper", DefaultXmppHeaderMapper.class);
List<String> requestHeaderNames = TestUtils.getPropertyValue(headerMapper, "requestHeaderNames", List.class);
assertEquals(2, requestHeaderNames.size());
assertEquals("foo*", requestHeaderNames.get(0));
assertEquals("bar*", requestHeaderNames.get(1));
assertTrue(eventConsumer instanceof EventDrivenConsumer);
}
@SuppressWarnings("rawtypes")
@Test
public void testPollingConsumerUsage() throws Exception{
Object pollingConsumer = context.getBean("outboundPollingAdapter");
public void withHeaderMapper() throws Exception{
Object pollingConsumer = context.getBean("withHeaderMapper");
assertTrue(pollingConsumer instanceof PollingConsumer);
assertEquals(headerMapper, TestUtils.getPropertyValue(pollingConsumer, "handler.headerMapper"));
MessageChannel channel = context.getBean("outboundEventChannel", MessageChannel.class);
Message<?> message = MessageBuilder.withPayload("hello").setHeader(XmppHeaders.CHAT_TO, "oleg").build();
Message<?> message = MessageBuilder.withPayload("hello").setHeader(XmppHeaders.TO, "oleg").
setHeader("foobar", "foobar").build();
XMPPConnection connection = context.getBean("testConnection", XMPPConnection.class);
Mockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
org.jivesoftware.smack.packet.Message xmppMessage = (org.jivesoftware.smack.packet.Message) args[0];
assertEquals("oleg", xmppMessage.getTo());
assertEquals("foobar", xmppMessage.getProperty("foobar"));
assertEquals("oleg", xmppMessage.getTo());
return null;
}})
.when(connection).sendPacket(Mockito.any(org.jivesoftware.smack.packet.Message.class));
channel.send(message);
verify(connection, times(1)).sendPacket(Mockito.any(org.jivesoftware.smack.packet.Message.class));
}

View File

@@ -0,0 +1,144 @@
/*
* Copyright 2002-2011 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.xmpp.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.util.HashMap;
import java.util.Map;
import org.jivesoftware.smack.packet.Message;
import org.junit.Test;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.xmpp.XmppHeaders;
/**
* @author Mark Fisher
* @since 2.1
*/
public class DefaultXmppHeaderMapperTests {
@Test
public void fromHeadersStandardOutbound() {
DefaultXmppHeaderMapper mapper = new DefaultXmppHeaderMapper();
Map<String, Object> headerMap = new HashMap<String, Object>();
headerMap.put("userDefined1", "foo");
headerMap.put("userDefined2", "bar");
headerMap.put(XmppHeaders.THREAD, "test.thread");
headerMap.put(XmppHeaders.TO, "test.to");
headerMap.put(XmppHeaders.FROM, "test.from");
headerMap.put(XmppHeaders.SUBJECT, "test.subject");
headerMap.put(XmppHeaders.TYPE, "headline");
MessageHeaders headers = new MessageHeaders(headerMap);
Message target = new Message();
mapper.fromHeadersToRequest(headers, target);
// "standard" XMPP headers
assertEquals("test.thread", target.getThread());
assertEquals("test.to", target.getTo());
assertEquals("test.from", target.getFrom());
assertEquals("test.subject", target.getSubject());
assertEquals(Message.Type.headline, target.getType());
// user-defined headers not included by default
assertNull(target.getProperty("userDefined1"));
assertNull(target.getProperty("userDefined2"));
// transient headers should not be copied
assertNull(target.getProperty("id"));
assertNull(target.getProperty("timestamp"));
}
@Test
public void fromHeadersUserDefinedOnly() {
DefaultXmppHeaderMapper mapper = new DefaultXmppHeaderMapper();
mapper.setRequestHeaderNames(new String[] { "userDefined1", "userDefined2" });
Map<String, Object> headerMap = new HashMap<String, Object>();
headerMap.put("userDefined1", "foo");
headerMap.put("userDefined2", "bar");
headerMap.put("userDefined3", "baz");
headerMap.put(XmppHeaders.THREAD, "test.thread");
headerMap.put(XmppHeaders.TO, "test.to");
headerMap.put(XmppHeaders.FROM, "test.from");
headerMap.put(XmppHeaders.SUBJECT, "test.subject");
headerMap.put(XmppHeaders.TYPE, "headline");
MessageHeaders headers = new MessageHeaders(headerMap);
Message target = new Message();
mapper.fromHeadersToRequest(headers, target);
// "standard" XMPP headers not included
assertNull(target.getThread());
assertNull(target.getTo());
assertNull(target.getFrom());
assertNull(target.getSubject());
assertEquals(Message.Type.normal, target.getType());
// user-defined headers are included if in the list
assertEquals("foo", target.getProperty("userDefined1"));
assertEquals("bar", target.getProperty("userDefined2"));
// user-defined headers are not included if not in the list
assertNull(target.getProperty("userDefined3"));
// transient headers should not be copied
assertNull(target.getProperty("id"));
assertNull(target.getProperty("timestamp"));
}
@Test
public void toHeadersStandardOnly() {
DefaultXmppHeaderMapper mapper = new DefaultXmppHeaderMapper();
Message source = new Message("test.to", Message.Type.headline);
source.setFrom("test.from");
source.setSubject("test.subject");
source.setThread("test.thread");
source.setProperty("userDefined1", "foo");
source.setProperty("userDefined2", "bar");
Map<String, Object> headers = mapper.toHeadersFromRequest(source);
assertEquals("test.to", headers.get(XmppHeaders.TO));
assertEquals("test.from", headers.get(XmppHeaders.FROM));
assertEquals("test.subject", headers.get(XmppHeaders.SUBJECT));
assertEquals("test.thread", headers.get(XmppHeaders.THREAD));
assertEquals(Message.Type.headline, headers.get(XmppHeaders.TYPE));
assertNull(headers.get("userDefined1"));
assertNull(headers.get("userDefined2"));
}
@Test
public void toHeadersUserDefinedOnly() {
DefaultXmppHeaderMapper mapper = new DefaultXmppHeaderMapper();
mapper.setReplyHeaderNames(new String[] { "userDefined*" });
Message source = new Message("test.to", Message.Type.headline);
source.setFrom("test.from");
source.setSubject("test.subject");
source.setThread("test.thread");
source.setProperty("userDefined1", "foo");
source.setProperty("userDefined2", "bar");
Map<String, Object> headers = mapper.toHeadersFromReply(source);
assertNull(headers.get(XmppHeaders.TO));
assertNull(headers.get(XmppHeaders.FROM));
assertNull(headers.get(XmppHeaders.SUBJECT));
assertNull(headers.get(XmppHeaders.THREAD));
assertNull(headers.get(XmppHeaders.TYPE));
assertEquals("foo", headers.get("userDefined1"));
assertEquals("bar", headers.get("userDefined2"));
}
}