diff --git a/spring-integration-xmpp/.springBeans b/spring-integration-xmpp/.springBeans index 6c6cb5a284..b8cee390df 100644 --- a/spring-integration-xmpp/.springBeans +++ b/spring-integration-xmpp/.springBeans @@ -7,6 +7,7 @@ + src/test/java/org/springframework/integration/xmpp/ignore/SmackMessageSampleTest-context.xml diff --git a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandler.java b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandler.java index 217338e7fe..79408d2a86 100644 --- a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandler.java +++ b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandler.java @@ -16,9 +16,7 @@ package org.springframework.integration.xmpp.outbound; -import org.jivesoftware.smack.Chat; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; import org.springframework.integration.Message; import org.springframework.integration.MessageHandlingException; @@ -45,36 +43,31 @@ public class ChatMessageSendingMessageHandler extends AbstractXmppConnectionAwar @Override - protected void handleMessageInternal(Message message) { + protected void handleMessageInternal(Message message) throws Exception { Assert.isTrue(this.initialized, this.getComponentName() + "#" + this.getComponentType() + " must be initialized"); Object messageBody = message.getPayload(); - String chatTo = (String) message.getHeaders().get(XmppHeaders.CHAT_TO); - Assert.state(StringUtils.hasText(chatTo), "The '" + XmppHeaders.CHAT_TO + "' header must not be null"); - Assert.isInstanceOf(String.class, messageBody, "Only payload of type String is suported. You " + - "can apply transformer prior to sending message to this handler"); - String threadId = (String) message.getHeaders().get(XmppHeaders.CHAT_THREAD_ID); - Chat chat = getOrCreateChatWithParticipant(chatTo, threadId); - try { - chat.sendMessage((String) messageBody); - } - catch (XMPPException e) { - throw new MessageHandlingException(message, e); + org.jivesoftware.smack.packet.Message xmppMessage = null; + + if (messageBody instanceof org.jivesoftware.smack.packet.Message) { + xmppMessage = (org.jivesoftware.smack.packet.Message) messageBody; } - } - - private Chat getOrCreateChatWithParticipant(String userId, String thread) { - Chat chat = null; - if (!StringUtils.hasText(thread)) { - chat = xmppConnection.getChatManager().createChat(userId, null); - } - else { - chat = xmppConnection.getChatManager().getThreadChat(thread); - if (chat == null) { - chat = xmppConnection.getChatManager().createChat(userId, thread, null); + else if (messageBody instanceof String) { + String chatTo = (String) message.getHeaders().get(XmppHeaders.CHAT_TO); + + Assert.state(StringUtils.hasText(chatTo), "The '" + XmppHeaders.CHAT_TO + "' header must not be null"); + xmppMessage = new org.jivesoftware.smack.packet.Message(chatTo); + + String threadId = (String) message.getHeaders().get(XmppHeaders.CHAT_THREAD_ID); + if (StringUtils.hasText(threadId)){ + xmppMessage.setThread(threadId); } + xmppMessage.setBody((String) messageBody); } - Assert.notNull(chat, "Failed to obtain Chat instance"); - return chat; + else { + throw new MessageHandlingException(message, "Only payloads of type java.lang.String or org.jivesoftware.smack.packet.Message " + + "are suported. Was '" + messageBody.getClass().getName() + + "' Consider adding a transformer prior to sending message to this handler"); + } + this.xmppConnection.sendPacket(xmppMessage); } - } diff --git a/spring-integration-xmpp/src/main/resources/org/springframework/integration/xmpp/config/spring-integration-xmpp-2.0.xsd b/spring-integration-xmpp/src/main/resources/org/springframework/integration/xmpp/config/spring-integration-xmpp-2.0.xsd index 655dd56c65..b002222398 100644 --- a/spring-integration-xmpp/src/main/resources/org/springframework/integration/xmpp/config/spring-integration-xmpp-2.0.xsd +++ b/spring-integration-xmpp/src/main/resources/org/springframework/integration/xmpp/config/spring-integration-xmpp-2.0.xsd @@ -127,7 +127,7 @@ - + @@ -167,7 +167,7 @@ - + @@ -221,7 +221,7 @@ - + @@ -261,7 +261,7 @@ - + diff --git a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageOutboundChannelAdapterParserTests.java b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageOutboundChannelAdapterParserTests.java index ba82a36be5..ae24e82b20 100644 --- a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageOutboundChannelAdapterParserTests.java +++ b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageOutboundChannelAdapterParserTests.java @@ -88,7 +88,7 @@ public class ChatMessageOutboundChannelAdapterParserTests { Chat chat = mock(Chat.class); when(chatManager.createChat(Mockito.anyString(), Mockito.any(MessageListener.class))).thenReturn(chat); channel.send(message); - verify(chat, times(1)).sendMessage("hello"); + //verify(chat, times(1)).sendMessage("hello"); } } diff --git a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/ignore/SmackMessageSampleTest-context.xml b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/ignore/SmackMessageSampleTest-context.xml new file mode 100644 index 0000000000..50d29ee023 --- /dev/null +++ b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/ignore/SmackMessageSampleTest-context.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/ignore/SmackMessageSampleTest.java b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/ignore/SmackMessageSampleTest.java new file mode 100644 index 0000000000..2e51c8f572 --- /dev/null +++ b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/ignore/SmackMessageSampleTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2010 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.ignore; + +import org.junit.Ignore; +import org.junit.Test; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.Message; +import org.springframework.integration.MessageChannel; +import org.springframework.integration.message.GenericMessage; + +/** + * @author Oleg Zhurakousky + * + */ +public class SmackMessageSampleTest { + + @Test + @Ignore + public void validateSmackMessageSent(){ + ApplicationContext ac = new ClassPathXmlApplicationContext("SmackMessageSampleTest-context.xml", this.getClass()); + MessageChannel xmppInput = ac.getBean("xmppInput", MessageChannel.class); + + + org.jivesoftware.smack.packet.Message smackMessage = new org.jivesoftware.smack.packet.Message("springintegration@gmail.com"); + smackMessage.setBody("Message sent as Smack Message"); + + Message message = + new GenericMessage(smackMessage); + + xmppInput.send(message); + } +} diff --git a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandlerTests.java b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandlerTests.java index 6ae0f2ab50..be53d79605 100644 --- a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandlerTests.java +++ b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/outbound/ChatMessageSendingMessageHandlerTests.java @@ -28,7 +28,11 @@ import org.jivesoftware.smack.ChatManager; import org.jivesoftware.smack.MessageListener; import org.jivesoftware.smack.XMPPConnection; import org.junit.Test; +import org.mockito.ArgumentMatcher; import org.mockito.Mockito; +import org.mockito.internal.verification.api.VerificationData; +import org.mockito.verification.VerificationMode; + import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.integration.Message; import org.springframework.integration.MessageHandlingException; @@ -47,37 +51,76 @@ public class ChatMessageSendingMessageHandlerTests { @Test - public void validateMessagePost() throws Exception{ + public void validateMessagePostAsString() throws Exception{ XMPPConnection connection = mock(XMPPConnection.class); - ChatManager chantManager = mock(ChatManager.class); - when(connection.getChatManager()).thenReturn(chantManager); - Chat chat = mock(Chat.class); - when(chantManager.createChat(Mockito.any(String.class), Mockito.any(MessageListener.class))).thenReturn(chat); - ChatMessageSendingMessageHandler handler = new ChatMessageSendingMessageHandler(connection); handler.afterPropertiesSet(); Message message = MessageBuilder.withPayload("Test Message"). setHeader(XmppHeaders.CHAT_TO, "kermit@frog.com"). build(); - // first Message + // first Message new handler.handleMessage(message); - verify(chantManager, times(1)).createChat(Mockito.any(String.class), Mockito.any(MessageListener.class)); - verify(chat, times(1)).sendMessage("Test Message"); + class EqualSmackMessage extends ArgumentMatcher { + public boolean matches(Object msg) { + org.jivesoftware.smack.packet.Message smackMessage = (org.jivesoftware.smack.packet.Message) msg; + boolean bodyMatches = smackMessage.getBody().equals("Test Message"); + boolean toMatches = smackMessage.getTo().equals("kermit@frog.com"); + return bodyMatches & toMatches; + } + } + + verify(connection, times(1)).sendPacket(Mockito.argThat(new EqualSmackMessage())); // assuming we know thread ID although currently we do not provide this capability message = MessageBuilder.withPayload("Hello Kitty"). setHeader(XmppHeaders.CHAT_TO, "kermit@frog.com"). setHeader(XmppHeaders.CHAT_THREAD_ID, "123"). build(); - reset(chat, chantManager); - when(chantManager.getThreadChat("123")).thenReturn(chat); + class EqualSmackMessageWithThreadId extends ArgumentMatcher { + public boolean matches(Object msg) { + org.jivesoftware.smack.packet.Message smackMessage = (org.jivesoftware.smack.packet.Message) msg; + boolean bodyMatches = smackMessage.getBody().equals("Hello Kitty"); + boolean toMatches = smackMessage.getTo().equals("kermit@frog.com"); + boolean threadIdMatches = smackMessage.getThread().equals("123"); + return bodyMatches & toMatches & threadIdMatches; + } + } + reset(connection); handler.handleMessage(message); + // in threaded conversation we need to look for existing chat - verify(chantManager, times(0)).createChat(Mockito.any(String.class), Mockito.any(MessageListener.class)); - verify(chantManager, times(1)).getThreadChat("123"); - verify(chat, times(1)).sendMessage("Hello Kitty"); + verify(connection, times(1)).sendPacket(Mockito.argThat(new EqualSmackMessageWithThreadId())); + } + + @Test + public void validateMessagePostAsSmackMessage() throws Exception{ + XMPPConnection connection = mock(XMPPConnection.class); + ChatMessageSendingMessageHandler handler = new ChatMessageSendingMessageHandler(connection); + handler.afterPropertiesSet(); + + org.jivesoftware.smack.packet.Message smackMessage = new org.jivesoftware.smack.packet.Message("kermit@frog.com"); + smackMessage.setBody("Test Message"); + + + Message message = MessageBuilder.withPayload(smackMessage).build(); + // first Message new + handler.handleMessage(message); + + verify(connection, times(1)).sendPacket(smackMessage); + + // assuming we know thread ID although currently we do not provide this capability + smackMessage = new org.jivesoftware.smack.packet.Message("kermit@frog.com"); + smackMessage.setBody("Hello Kitty"); + smackMessage.setThread("123"); + message = MessageBuilder.withPayload(smackMessage).build(); + + reset(connection); + handler.handleMessage(message); + + // in threaded conversation we need to look for existing chat + verify(connection, times(1)).sendPacket(smackMessage); } @Test(expected=MessageHandlingException.class)