You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by be...@apache.org on 2010/04/21 21:09:49 UTC

svn commit: r936448 - in /mina/vysper/trunk/server/core/src: main/java/org/apache/vysper/xmpp/modules/core/base/handler/ main/java/org/apache/vysper/xmpp/modules/core/base/handler/async/ main/java/org/apache/vysper/xmpp/modules/core/compatibility/jabbe...

Author: berndf
Date: Wed Apr 21 19:09:49 2010
New Revision: 936448

URL: http://svn.apache.org/viewvc?rev=936448&view=rev
Log:
VYSPER-199: deliver IQ stanzas from client-to-client

Added:
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/roster/persistence/RosterManagerUtils.java
    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandlerTestCase.java
Modified:
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/DefaultIQHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/IQHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/async/AbstractAsyncIQGetHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/compatibility/jabber_iq_auth/handler/AuthCompatibilityIQHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/session/handler/SessionIQHandler.java
    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java
    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/TestIQHandler.java

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/DefaultIQHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/DefaultIQHandler.java?rev=936448&r1=936447&r2=936448&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/DefaultIQHandler.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/DefaultIQHandler.java Wed Apr 21 19:09:49 2010
@@ -59,7 +59,7 @@ public abstract class DefaultIQHandler e
     protected abstract boolean verifyNamespace(Stanza stanza);
 
     @Override
-    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
+    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, boolean outboundStanza, SessionContext sessionContext) {
 
         switch (stanza.getIQType()) {
             case ERROR:

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/IQHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/IQHandler.java?rev=936448&r1=936447&r2=936448&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/IQHandler.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/IQHandler.java Wed Apr 21 19:09:49 2010
@@ -117,7 +117,7 @@ public class IQHandler extends XMPPCoreS
         }
 
 
-        return executeIQLogic(stanza, serverRuntimeContext, sessionContext);
+        return executeIQLogic(stanza, serverRuntimeContext, isOutboundStanza, sessionContext);
     }
 
     protected String getErrorLanguage(ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
@@ -128,7 +128,7 @@ public class IQHandler extends XMPPCoreS
     /**
      * must be overridden by specialized IQ handlers
      */
-    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
+    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, boolean outboundStanza, SessionContext sessionContext) {
         // this is default behavior and must be replaced by overrider
         return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.FEATURE_NOT_IMPLEMENTED, stanza,
                 StanzaErrorType.CANCEL,

Added: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java?rev=936448&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java (added)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandler.java Wed Apr 21 19:09:49 2010
@@ -0,0 +1,107 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.vysper.xmpp.modules.core.base.handler;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.delivery.failure.DeliveryException;
+import org.apache.vysper.xmpp.delivery.failure.ReturnErrorToSenderFailureStrategy;
+import org.apache.vysper.xmpp.modules.roster.persistence.RosterManager;
+import org.apache.vysper.xmpp.modules.roster.persistence.RosterManagerUtils;
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.apache.vysper.xmpp.server.SessionContext;
+import org.apache.vysper.xmpp.server.response.ServerErrorResponses;
+import org.apache.vysper.xmpp.stanza.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * most IQ are targeted to the server. but sometimes, IQs are only routed through the server to another client.
+ * this is the handler dealing with that. 
+ */
+public class RelayingIQHandler extends IQHandler {
+
+    final Logger logger = LoggerFactory.getLogger(RelayingIQHandler.class);
+
+    @Override
+    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, boolean outboundStanza, SessionContext sessionContext) {
+        // only handle IQs which are not directed to the server.
+        // in the case where an IQ is send to the server, StanzaHandlerLookup.getIQHandler is responsible for
+        // looking it up and we shouldn't have been come here in the first place.
+        Entity to = stanza.getTo();
+        if (to == null || to.equals(sessionContext.getServerJID())) {
+            return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.FEATURE_NOT_IMPLEMENTED, stanza,
+                    StanzaErrorType.CANCEL,
+                    null, null, null);
+        }
+
+        RosterManager rosterManager = RosterManagerUtils.getRosterInstance(serverRuntimeContext, sessionContext);
+
+        if (outboundStanza) {
+            try {
+                Entity from = stanza.getFrom();
+                if (from == null || !from.isResourceSet()) {
+                    from = new EntityImpl(sessionContext.getInitiatingEntity(), serverRuntimeContext.getResourceRegistry().getUniqueResourceForSession(sessionContext));
+                }
+
+                // determine if the is a matching subscription...
+                boolean isFromContact;
+                try {
+                    isFromContact = rosterManager.retrieve(from.getBareJID()).getEntry(to.getBareJID()).hasFrom();
+                } catch (Exception e) {
+                    isFromContact = false;
+                }
+                // ...otherwise relaying is denied
+                if (!isFromContact) {
+                    return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.SERVICE_UNAVAILABLE, stanza,
+                            StanzaErrorType.CANCEL,
+                            null, null, null);
+                }
+
+                Stanza forwardedStanza = StanzaBuilder.createForward(stanza, from, null).build();
+                serverRuntimeContext.getStanzaRelay().relay(to, forwardedStanza, new ReturnErrorToSenderFailureStrategy(serverRuntimeContext.getStanzaRelay()));
+            } catch (DeliveryException e) {
+                final Logger logger = LoggerFactory.getLogger(RelayingIQHandler.class);
+            }
+        } else {
+            // write inbound stanza to the user
+
+            Entity from = stanza.getFrom();
+            
+            // determine if the is a matching subscription...
+            boolean isToContact;
+            try {
+                isToContact = rosterManager.retrieve(to.getBareJID()).getEntry(from.getBareJID()).hasTo();
+            } catch (Exception e) {
+                isToContact = false;
+            }
+            // ...otherwise relaying is denied
+            if (!isToContact) {
+                return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.SERVICE_UNAVAILABLE, stanza,
+                        StanzaErrorType.CANCEL,
+                        null, null, null);
+            }
+
+            sessionContext.getResponseWriter().write(stanza);
+        }
+
+        return null;
+    }
+}

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/async/AbstractAsyncIQGetHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/async/AbstractAsyncIQGetHandler.java?rev=936448&r1=936447&r2=936448&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/async/AbstractAsyncIQGetHandler.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/base/handler/async/AbstractAsyncIQGetHandler.java Wed Apr 21 19:09:49 2010
@@ -49,7 +49,7 @@ abstract public class AbstractAsyncIQGet
     abstract protected RunnableFuture<XMPPCoreStanza> createGetTask(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext);
 
     @Override
-    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
+    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, boolean outboundStanza, SessionContext sessionContext) {
         switch (stanza.getIQType()) {
             case GET:
                 executeGetIQLogicAsync(stanza, serverRuntimeContext, sessionContext);

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/compatibility/jabber_iq_auth/handler/AuthCompatibilityIQHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/compatibility/jabber_iq_auth/handler/AuthCompatibilityIQHandler.java?rev=936448&r1=936447&r2=936448&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/compatibility/jabber_iq_auth/handler/AuthCompatibilityIQHandler.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/compatibility/jabber_iq_auth/handler/AuthCompatibilityIQHandler.java Wed Apr 21 19:09:49 2010
@@ -44,7 +44,7 @@ public class AuthCompatibilityIQHandler 
     }
 
     @Override
-    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
+    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, boolean outboundStanza, SessionContext sessionContext) {
 
         // from XEP 78 - http://www.xmpp.org/extensions/xep-0078.html:
         // If the server does not support non-SASL authentication (e.g., because it supports only SASL authentication

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandler.java?rev=936448&r1=936447&r2=936448&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandler.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/im/handler/PresenceHandler.java Wed Apr 21 19:09:49 2010
@@ -21,6 +21,7 @@ package org.apache.vysper.xmpp.modules.c
 
 import org.apache.vysper.xmpp.modules.core.base.handler.XMPPCoreStanzaHandler;
 import org.apache.vysper.xmpp.modules.roster.persistence.RosterManager;
+import org.apache.vysper.xmpp.modules.roster.persistence.RosterManagerUtils;
 import org.apache.vysper.xmpp.server.SessionContext;
 import org.apache.vysper.xmpp.server.ServerRuntimeContext;
 import org.apache.vysper.xmpp.stanza.PresenceStanza;
@@ -54,15 +55,8 @@ public class PresenceHandler extends XMP
 
         boolean subscriptionRelated = isSubscriptionType(presenceStanza.getPresenceType());
 
-        RosterManager rosterManager = null;
-        try {
-            rosterManager = (RosterManager)serverRuntimeContext.getStorageProvider(RosterManager.class);
-        } catch (Exception e) {
-            // System.err.println("failed to retrieve roster manager for session id = " + sessionContext.getSessionId());
-            String sessionId = sessionContext == null ? "NO_SESSION" : sessionContext.getSessionId();
-            throw new RuntimeException("failed to retrieve roster manager for session id = " + sessionId);
-        }
-
+        RosterManager rosterManager = RosterManagerUtils.getRosterInstance(serverRuntimeContext, sessionContext);
+        
         if (!subscriptionRelated) return AVAILABILITY_HANDLER.executeCorePresence(serverRuntimeContext, isOutboundStanza, sessionContext, presenceStanza, rosterManager);
         else return SUBSCRIPTION_HANDLER.executeCorePresence(serverRuntimeContext, isOutboundStanza, sessionContext, presenceStanza, rosterManager);
     }

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/session/handler/SessionIQHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/session/handler/SessionIQHandler.java?rev=936448&r1=936447&r2=936448&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/session/handler/SessionIQHandler.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/core/session/handler/SessionIQHandler.java Wed Apr 21 19:09:49 2010
@@ -41,7 +41,7 @@ public class SessionIQHandler extends IQ
     }
 
     @Override
-    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
+    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, boolean outboundStanza, SessionContext sessionContext) {
 
         switch (stanza.getIQType()) {
 
@@ -58,4 +58,4 @@ public class SessionIQHandler extends IQ
         return null;
     }
 
-}
\ No newline at end of file
+}

Added: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/roster/persistence/RosterManagerUtils.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/roster/persistence/RosterManagerUtils.java?rev=936448&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/roster/persistence/RosterManagerUtils.java (added)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/roster/persistence/RosterManagerUtils.java Wed Apr 21 19:09:49 2010
@@ -0,0 +1,29 @@
+package org.apache.vysper.xmpp.modules.roster.persistence;
+
+import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.apache.vysper.xmpp.server.SessionContext;
+
+/**
+ */
+public class RosterManagerUtils {
+
+    /**
+     * retrieves the roster manager from the server runtime context and throws exception if not present
+     *
+     * @param serverRuntimeContext
+     * @param sessionContext
+     * @return roster manager - will not be NULL
+     * @throws RuntimeException iff roster manager cannot be retrieved
+     */
+    public static RosterManager getRosterInstance(ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
+        RosterManager rosterManager;
+        try {
+            rosterManager = (RosterManager)serverRuntimeContext.getStorageProvider(RosterManager.class);
+        } catch (Exception e) {
+            // System.err.println("failed to retrieve roster manager for session id = " + sessionContext.getSessionId());
+            String sessionId = sessionContext == null ? "NO_SESSION" : sessionContext.getSessionId();
+            throw new RuntimeException("failed to retrieve roster manager for session id = " + sessionId);
+        }
+        return rosterManager;
+    }
+}

Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java?rev=936448&r1=936447&r2=936448&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java (original)
+++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/protocol/StanzaHandlerLookup.java Wed Apr 21 19:09:49 2010
@@ -25,6 +25,7 @@ import java.util.Map;
 import org.apache.vysper.xml.fragment.XMLElement;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.modules.core.base.handler.IQHandler;
+import org.apache.vysper.xmpp.modules.core.base.handler.RelayingIQHandler;
 import org.apache.vysper.xmpp.modules.core.base.handler.MessageHandler;
 import org.apache.vysper.xmpp.modules.core.base.handler.StreamStartHandler;
 import org.apache.vysper.xmpp.modules.core.base.handler.XMLPrologHandler;
@@ -45,7 +46,7 @@ public class StanzaHandlerLookup {
 
     private Map<String, NamespaceHandlerDictionary> namespaceDictionaries = new LinkedHashMap<String, NamespaceHandlerDictionary>();
 
-    private IQHandler iqHandler = new IQHandler();
+    private IQHandler iqHandler = new RelayingIQHandler();
     private MessageHandler messageHandler = new MessageHandler();
     private PresenceHandler presenceHandler = new PresenceHandler();
     private static final ServiceUnavailableStanzaErrorHandler SERVICE_UNAVAILABLE_STANZA_ERROR_HANDLER = new ServiceUnavailableStanzaErrorHandler();
@@ -92,22 +93,21 @@ public class StanzaHandlerLookup {
     }
 
     private StanzaHandler getIQHandler(Stanza stanza) {
-        return getHandler(stanza, iqHandler);
-    }
-
-    private StanzaHandler getHandler(Stanza stanza, StanzaHandler defaultHandler) {
         StanzaHandler handlerForElement = null;
 
-        if (stanza.getVerifier().subElementsPresentExact(1)) {
+        Entity to = stanza.getTo();
+        boolean isAddressedToServer = (to == null || (!to.isNodeSet() && !to.isResourceSet()));
+        
+        if (isAddressedToServer && stanza.getVerifier().subElementsPresentExact(1)) {
             XMLElement firstInnerElement = stanza.getFirstInnerElement();
             handlerForElement = getHandlerForElement(stanza, firstInnerElement);
             return handlerForElement;
         } else {
             // if no specialized handler can be identified, return general handler
-            return defaultHandler;
+            return iqHandler;
         }
     }
-    
+
     /**
      * tries to find the handler by trying
      * 1. value of xmlElement's XMLNS attribute, if unique

Added: mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandlerTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandlerTestCase.java?rev=936448&view=auto
==============================================================================
--- mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandlerTestCase.java (added)
+++ mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/RelayingIQHandlerTestCase.java Wed Apr 21 19:09:49 2010
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.vysper.xmpp.modules.core.base.handler;
+
+import org.apache.vysper.xmpp.modules.core.im.handler.PresenceHandlerBaseTestCase;
+import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
+import org.apache.vysper.xmpp.stanza.*;
+
+/**
+ */
+public class RelayingIQHandlerTestCase extends PresenceHandlerBaseTestCase {
+
+    protected RelayingIQHandler relayingIQHandler = new RelayingIQHandler();
+
+    public void testIQClientToClient_Outbound_NotSubscribed() {
+        Stanza iqStanza = StanzaBuilder.createIQStanza(initiatingUser.getEntityFQ(), unrelatedUser.getEntityFQ(), IQStanzaType.GET, "test").startInnerElement("mandatory").build();
+
+        ResponseStanzaContainer stanzaContainer = relayingIQHandler.execute(iqStanza, sessionContext.getServerRuntimeContext(), true, sessionContext, null /*don't we have as sessionStateHolder?*/);
+        XMPPCoreStanza response = XMPPCoreStanza.getWrapper(stanzaContainer.getResponseStanza());
+        assertNotNull(response);
+        assertTrue(response.isError());
+    }
+
+    public void testIQClientToClient_Outbound() {
+        Stanza iqStanza = StanzaBuilder.createIQStanza(initiatingUser.getEntityFQ(), subscribed_FROM.getEntityFQ(), IQStanzaType.GET, "test").startInnerElement("mandatory").build();
+
+        ResponseStanzaContainer stanzaContainer = relayingIQHandler.execute(iqStanza, sessionContext.getServerRuntimeContext(), true, sessionContext, null /*don't we have as sessionStateHolder?*/);
+        assertNull(stanzaContainer);
+        Stanza deliveredStanza = subscribed_FROM.getNextStanza();
+        assertTrue(deliveredStanza.getVerifier().onlySubelementEquals("mandatory", null));
+        assertEquals(subscribed_FROM.getEntityFQ(), deliveredStanza.getTo());
+    }
+
+    public void testIQClientToClient_Inbound_NoTO() {
+        Stanza iqStanza = StanzaBuilder.createIQStanza(subscribed_FROM.getEntityFQ(), initiatingUser.getEntityFQ(), IQStanzaType.GET, "test").startInnerElement("mandatory").build();
+
+        ResponseStanzaContainer stanzaContainer = relayingIQHandler.execute(iqStanza, sessionContext.getServerRuntimeContext(), false, sessionContext, null /*don't we have as sessionStateHolder?*/);
+        XMPPCoreStanza response = XMPPCoreStanza.getWrapper(stanzaContainer.getResponseStanza());
+        assertNotNull(response);
+        assertTrue(response.isError());
+    }
+
+    public void testIQClientToClient_Inbound() {
+        Stanza iqStanza = StanzaBuilder.createIQStanza(subscribed_TO.getEntityFQ(), initiatingUser.getEntityFQ(), IQStanzaType.GET, "test").startInnerElement("mandatory").build();
+
+        ResponseStanzaContainer stanzaContainer = relayingIQHandler.execute(iqStanza, sessionContext.getServerRuntimeContext(), false, sessionContext, null /*don't we have as sessionStateHolder?*/);
+        assertNull(stanzaContainer);
+        Stanza deliveredStanza = sessionContext.getNextRecordedResponse();
+        assertTrue(deliveredStanza.getVerifier().onlySubelementEquals("mandatory", null));
+        assertEquals(initiatingUser.getEntityFQ(), deliveredStanza.getTo());
+    }
+}

Modified: mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/TestIQHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/TestIQHandler.java?rev=936448&r1=936447&r2=936448&view=diff
==============================================================================
--- mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/TestIQHandler.java (original)
+++ mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/core/base/handler/TestIQHandler.java Wed Apr 21 19:09:49 2010
@@ -52,7 +52,7 @@ public class TestIQHandler extends IQHan
     }
 
     @Override
-    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
+    protected Stanza executeIQLogic(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, boolean outboundStanza, SessionContext sessionContext) {
         incomingStanza = stanza;
 
         StanzaBuilder responseBuilder = new StanzaBuilder("iq", NamespaceURIs.JABBER_CLIENT, stanza.getNamespacePrefix());