mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Niklas Gustavsson <...@apache.org>
Subject Re: svn commit: r1084393 - in /mina/vysper/trunk/server/core/src: main/java/org/apache/vysper/xmpp/delivery/inbound/ main/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/ test/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/
Date Tue, 22 Mar 2011 22:43:23 GMT
Bernd,

could you please review this commit. I'm not very experienced with how
IQ stanza relaying is supposed to work.

/niklas

On Tue, Mar 22, 2011 at 11:40 PM,  <ngn@apache.org> wrote:
> Author: ngn
> Date: Tue Mar 22 22:40:49 2011
> New Revision: 1084393
>
> URL: http://svn.apache.org/viewvc?rev=1084393&view=rev
> Log:
> Implement relaying of IQ stanzas and disco IQ stanzas to a user with a full JID provided
(VYSPER-278)
>
> Modified:
>    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/inbound/DeliveringInternalInboundStanzaRelay.java
>    mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandler.java
>    mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandlerTestCase.java
>
> Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/inbound/DeliveringInternalInboundStanzaRelay.java
> URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/inbound/DeliveringInternalInboundStanzaRelay.java?rev=1084393&r1=1084392&r2=1084393&view=diff
> ==============================================================================
> --- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/inbound/DeliveringInternalInboundStanzaRelay.java
(original)
> +++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/delivery/inbound/DeliveringInternalInboundStanzaRelay.java
Tue Mar 22 22:40:49 2011
> @@ -232,7 +232,7 @@ public class DeliveringInternalInboundSt
>                 }
>             } else if (IQStanza.isOfType(stanza)) {
>                 // TODO handle on behalf of the user/client
> -                throw new RuntimeException("inbound IQ not yet handled");
> +                return relayToBestSessions(false);
>             }
>
>             return relayNotPossible();
>
> Modified: mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandler.java
> URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandler.java?rev=1084393&r1=1084392&r2=1084393&view=diff
> ==============================================================================
> --- mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandler.java
(original)
> +++ mina/vysper/trunk/server/core/src/main/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandler.java
Tue Mar 22 22:40:49 2011
> @@ -25,6 +25,8 @@ import org.apache.vysper.compliance.Spec
>  import org.apache.vysper.compliance.SpecCompliant;
>  import org.apache.vysper.xml.fragment.XMLElement;
>  import org.apache.vysper.xmpp.addressing.Entity;
> +import org.apache.vysper.xmpp.delivery.failure.DeliveryException;
> +import org.apache.vysper.xmpp.delivery.failure.ReturnErrorToSenderFailureStrategy;
>  import org.apache.vysper.xmpp.modules.core.base.handler.DefaultIQHandler;
>  import org.apache.vysper.xmpp.modules.servicediscovery.collection.ServiceCollector;
>  import org.apache.vysper.xmpp.modules.servicediscovery.collection.ServiceDiscoveryRequestListenerRegistry;
> @@ -58,7 +60,8 @@ public class DiscoInfoIQHandler extends
>
>     @Override
>     protected boolean verifyInnerElement(Stanza stanza) {
> -        return verifyInnerElementWorker(stanza, "query") && verifyInnerNamespace(stanza,
NamespaceURIs.XEP0030_SERVICE_DISCOVERY_INFO);
> +        return verifyInnerElementWorker(stanza, "query")
> +                && verifyInnerNamespace(stanza, NamespaceURIs.XEP0030_SERVICE_DISCOVERY_INFO);
>     }
>
>     @Override
> @@ -78,8 +81,8 @@ public class DiscoInfoIQHandler extends
>         }
>
>         if (serviceCollector == null) {
> -            return ServerErrorResponses.getStanzaError(StanzaErrorCondition.INTERNAL_SERVER_ERROR,
> -                    stanza, StanzaErrorType.CANCEL, "cannot retrieve IQ-get-info
result from internal components",
> +            return ServerErrorResponses.getStanzaError(StanzaErrorCondition.INTERNAL_SERVER_ERROR,
stanza,
> +                    StanzaErrorType.CANCEL, "cannot retrieve IQ-get-info result
from internal components",
>                     getErrorLanguage(serverRuntimeContext, sessionContext),
null);
>         }
>
> @@ -109,25 +112,30 @@ public class DiscoInfoIQHandler extends
>         List<InfoElement> elements = null;
>         try {
>             Entity from = stanza.getFrom();
> -            if (from == null) from = sessionContext.getInitiatingEntity();
> +            if (from == null)
> +                from = sessionContext.getInitiatingEntity();
>             if (isServerInfoRequest) {
> -                elements = serviceCollector.processServerInfoRequest(new InfoRequest(from,
to, node, stanza
> -                        .getID()));
> +                elements = serviceCollector.processServerInfoRequest(new InfoRequest(from,
to, node, stanza.getID()));
>             } else if (isComponentInfoRequest) {
> -                elements = serviceCollector.processComponentInfoRequest(new
InfoRequest(from, to, node,
> -                        stanza.getID()));
> +                elements = serviceCollector
> +                        .processComponentInfoRequest(new InfoRequest(from,
to, node, stanza.getID()));
>             } else {
> -                elements = serviceCollector.processInfoRequest(new InfoRequest(from,
to, node, stanza
> -                        .getID()));
> +                // "When an entity sends a disco#info request to a bare JID
(<account@domain.tld>) hosted by a server,
> +                // the server itself MUST reply on behalf of the hosted account,
either with an IQ-error or an IQ-result"
> +                if (to.isResourceSet()) {
> +                    relayOrWrite(stanza, serverRuntimeContext, sessionContext);
> +                    return null;
> +                } else {
> +                    elements = serviceCollector.processInfoRequest(new InfoRequest(from,
to, node, stanza.getID()));
> +                }
>             }
>         } catch (ServiceDiscoveryRequestException e) {
>             // the request yields an error
>             StanzaErrorCondition stanzaErrorCondition = e.getErrorCondition();
>             if (stanzaErrorCondition == null)
>                 stanzaErrorCondition = StanzaErrorCondition.INTERNAL_SERVER_ERROR;
> -            return ServerErrorResponses.getStanzaError(stanzaErrorCondition, stanza,
> -                    StanzaErrorType.CANCEL, "disco info request failed.",
> -                    getErrorLanguage(serverRuntimeContext, sessionContext),
null);
> +            return ServerErrorResponses.getStanzaError(stanzaErrorCondition, stanza,
StanzaErrorType.CANCEL,
> +                    "disco info request failed.", getErrorLanguage(serverRuntimeContext,
sessionContext), null);
>         }
>
>         //TODO check that elementSet contains at least one identity element and on
feature element!
> @@ -146,4 +154,36 @@ public class DiscoInfoIQHandler extends
>
>         return stanzaBuilder.build();
>     }
> +
> +    @Override
> +    protected Stanza handleResult(IQStanza stanza, ServerRuntimeContext serverRuntimeContext,
> +            SessionContext sessionContext) {
> +
> +        if (stanza.getTo().isResourceSet()) {
> +            relayOrWrite(stanza, serverRuntimeContext, sessionContext);
> +            return null;
> +        } else {
> +            return super.handleResult(stanza, serverRuntimeContext, sessionContext);
> +        }
> +    }
> +
> +    private void relayOrWrite(IQStanza stanza, ServerRuntimeContext serverRuntimeContext,
SessionContext sessionContext) {
> +        boolean isOutbound = !sessionContext.getInitiatingEntity().equals(stanza.getTo().getBareJID());
> +        if (isOutbound) {
> +            try {
> +                Entity from = stanza.getFrom();
> +                if (from == null) {
> +                    from = sessionContext.getInitiatingEntity();
> +                }
> +                Stanza forward = StanzaBuilder.createForwardStanza(stanza, from,
null);
> +
> +                serverRuntimeContext.getStanzaRelay().relay(stanza.getTo(),
forward,
> +                        new ReturnErrorToSenderFailureStrategy(serverRuntimeContext.getStanzaRelay()));
> +            } catch (DeliveryException e) {
> +                logger.warn("relaying IQ failed", e);
> +            }
> +        } else {
> +            sessionContext.getResponseWriter().write(stanza);
> +        }
> +    }
>  }
>
> Modified: mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandlerTestCase.java
> URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandlerTestCase.java?rev=1084393&r1=1084392&r2=1084393&view=diff
> ==============================================================================
> --- mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandlerTestCase.java
(original)
> +++ mina/vysper/trunk/server/core/src/test/java/org/apache/vysper/xmpp/modules/servicediscovery/handler/DiscoInfoIQHandlerTestCase.java
Tue Mar 22 22:40:49 2011
> @@ -27,6 +27,8 @@ import junit.framework.Assert;
>  import org.apache.vysper.StanzaAssert;
>  import org.apache.vysper.xmpp.addressing.Entity;
>  import org.apache.vysper.xmpp.addressing.EntityImpl;
> +import org.apache.vysper.xmpp.delivery.StanzaRelay;
> +import org.apache.vysper.xmpp.delivery.failure.DeliveryFailureStrategy;
>  import org.apache.vysper.xmpp.modules.servicediscovery.collection.ServiceCollector;
>  import org.apache.vysper.xmpp.modules.servicediscovery.collection.ServiceDiscoveryRequestListenerRegistry;
>  import org.apache.vysper.xmpp.modules.servicediscovery.management.Feature;
> @@ -44,6 +46,7 @@ import org.apache.vysper.xmpp.stanza.Sta
>  import org.apache.vysper.xmpp.stanza.StanzaBuilder;
>  import org.apache.vysper.xmpp.stanza.StanzaErrorCondition;
>  import org.apache.vysper.xmpp.stanza.XMPPCoreStanza;
> +import org.apache.vysper.xmpp.writer.StanzaWriter;
>  import org.junit.Before;
>  import org.junit.Test;
>  import org.mockito.Mockito;
> @@ -56,10 +59,13 @@ public class DiscoInfoIQHandlerTestCase
>     private static final Entity SERVER = EntityImpl.parseUnchecked("vysper.org");
>     private static final Entity COMPONENT = EntityImpl.parseUnchecked("comp.vysper.org");
>     private static final Entity USER = EntityImpl.parseUnchecked("user@vysper.org");
> +    private static final Entity USER_WITH_RESOURCE = EntityImpl.parseUnchecked("user@vysper.org/res1");
>
> -    private ServerRuntimeContext serverRuntimeContext = Mockito.mock(ServerRuntimeContext.class);
> -    private SessionContext sessionContext = Mockito.mock(SessionContext.class);
> -    private ServiceCollector serviceCollector = Mockito.mock(ServiceCollector.class);
> +    private ServerRuntimeContext serverRuntimeContext = mock(ServerRuntimeContext.class);
> +    private SessionContext sessionContext = mock(SessionContext.class);
> +    private ServiceCollector serviceCollector = mock(ServiceCollector.class);
> +    private StanzaRelay stanzaRelay = mock(StanzaRelay.class);
> +    private StanzaWriter stanzaWriter = mock(StanzaWriter.class);
>
>     private IQStanza stanza = (IQStanza) IQStanza.getWrapper(buildStanza());
>
> @@ -148,6 +154,8 @@ public class DiscoInfoIQHandlerTestCase
>             .thenReturn(serviceCollector);
>
>         when(serverRuntimeContext.getServerEnitity()).thenReturn(SERVER);
> +        when(serverRuntimeContext.getStanzaRelay()).thenReturn(stanzaRelay);
> +        when(sessionContext.getResponseWriter()).thenReturn(stanzaWriter);
>     }
>
>     @Test
> @@ -186,6 +194,32 @@ public class DiscoInfoIQHandlerTestCase
>     }
>
>     @Test
> +    public void handleGetToUserWithResource() throws Exception {
> +        when(sessionContext.getInitiatingEntity()).thenReturn(FROM);
> +
> +        IQStanza stanza = createRequest(USER_WITH_RESOURCE);
> +
> +        Stanza response = handler.handleGet(stanza, serverRuntimeContext, sessionContext);
> +
> +        Assert.assertNull(response);
> +
> +        verify(stanzaRelay).relay(eq(USER_WITH_RESOURCE), eq(stanza), any(DeliveryFailureStrategy.class));
> +    }
> +
> +    @Test
> +    public void handleGetToUserWithResourceInbound() throws Exception {
> +        when(sessionContext.getInitiatingEntity()).thenReturn(USER);
> +
> +        IQStanza stanza = createRequest(USER_WITH_RESOURCE);
> +
> +        Stanza response = handler.handleGet(stanza, serverRuntimeContext, sessionContext);
> +
> +        Assert.assertNull(response);
> +
> +        verify(stanzaWriter).write(stanza);
> +    }
> +
> +    @Test
>     public void handleGetToNonExistingComponent() throws Exception {
>         IQStanza stanza = createRequest(COMPONENT);
>
> @@ -253,6 +287,45 @@ public class DiscoInfoIQHandlerTestCase
>         StanzaAssert.assertEquals(expected, response);
>     }
>
> +    @Test
> +    public void handleResultToUserWithResource() throws Exception {
> +        when(sessionContext.getInitiatingEntity()).thenReturn(FROM);
> +
> +        IQStanza stanza = createRequest(USER_WITH_RESOURCE, IQStanzaType.RESULT);
> +
> +        Stanza response = handler.handleResult(stanza, serverRuntimeContext, sessionContext);
> +
> +        Assert.assertNull(response);
> +
> +        verify(stanzaRelay).relay(eq(USER_WITH_RESOURCE), eq(stanza), any(DeliveryFailureStrategy.class));
> +    }
> +
> +    @Test
> +    public void handleResultToUserWithResourceInbound() throws Exception {
> +        when(sessionContext.getInitiatingEntity()).thenReturn(USER);
> +
> +        IQStanza stanza = createRequest(USER_WITH_RESOURCE, IQStanzaType.RESULT);
> +
> +        Stanza response = handler.handleResult(stanza, serverRuntimeContext, sessionContext);
> +
> +        Assert.assertNull(response);
> +
> +        verify(stanzaWriter).write(stanza);
> +    }
> +
> +    @Test
> +    public void handleResultToUser() throws Exception {
> +        when(sessionContext.getInitiatingEntity()).thenReturn(FROM);
> +
> +        IQStanza stanza = createRequest(USER, IQStanzaType.RESULT);
> +
> +        Stanza response = handler.handleResult(stanza, serverRuntimeContext, sessionContext);
> +
> +        Stanza expected = createErrorResponse(SERVER, "feature-not-implemented");
> +
> +        StanzaAssert.assertEquals(expected, response);
> +    }
> +
>     private Stanza createErrorResponse(Entity from, String error) {
>         Stanza expected = StanzaBuilder.createIQStanza(from, FROM, IQStanzaType.ERROR,
"id1")
>         .startInnerElement("query", NamespaceURIs.XEP0030_SERVICE_DISCOVERY_INFO)
> @@ -266,7 +339,11 @@ public class DiscoInfoIQHandlerTestCase
>     }
>
>     private IQStanza createRequest(Entity to) {
> -        IQStanza stanza = (IQStanza) XMPPCoreStanza.getWrapper(StanzaBuilder.createIQStanza(FROM,
to, IQStanzaType.GET, "id1")
> +        return createRequest(to, IQStanzaType.GET);
> +    }
> +
> +    private IQStanza createRequest(Entity to, IQStanzaType type) {
> +        IQStanza stanza = (IQStanza) XMPPCoreStanza.getWrapper(StanzaBuilder.createIQStanza(FROM,
to, type, "id1")
>                 .startInnerElement("query", NamespaceURIs.XEP0030_SERVICE_DISCOVERY_INFO)
>                 .addAttribute("node", "n")
>                 .build());
>
>
>

Mime
View raw message