/* * 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.delivery.inbound; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.vysper.xml.fragment.XMLSemanticError; import org.apache.vysper.xmpp.addressing.Entity; import org.apache.vysper.xmpp.addressing.EntityFormatException; import org.apache.vysper.xmpp.addressing.EntityImpl; import org.apache.vysper.xmpp.authentication.AccountCreationException; import org.apache.vysper.xmpp.authentication.AccountManagement; import org.apache.vysper.xmpp.delivery.failure.DeliveryException; import org.apache.vysper.xmpp.delivery.failure.IgnoreFailureStrategy; import org.apache.vysper.xmpp.delivery.failure.ServiceNotAvailableException; import org.apache.vysper.xmpp.server.DefaultServerRuntimeContext; import org.apache.vysper.xmpp.server.SessionState; import org.apache.vysper.xmpp.server.TestSessionContext; import org.apache.vysper.xmpp.stanza.Stanza; import org.apache.vysper.xmpp.stanza.StanzaBuilder; import org.apache.vysper.xmpp.state.resourcebinding.BindException; import org.apache.vysper.xmpp.state.resourcebinding.DefaultResourceRegistry; import org.apache.vysper.xmpp.state.resourcebinding.ResourceRegistry; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** */ public class DeliveringInteralInboundStanzaRelayTestCase extends TestCase { protected static final EntityImpl TO_ENTITY = EntityImpl.parseUnchecked("userTo@vysper.org"); protected static final EntityImpl FROM_ENTITY = EntityImpl.parseUnchecked("userFrom@vysper.org"); protected ResourceRegistry resourceRegistry = new DefaultResourceRegistry(); protected AccountManagement accountVerification; protected DeliveringInternalInboundStanzaRelay stanzaRelay; static class AccountVerificationMock implements AccountManagement { public void addUser(Entity username, String password) throws AccountCreationException { ; // empty } public boolean verifyAccountExists(Entity jid) { return true; } public void changePassword(Entity username, String password) throws AccountCreationException { ; // empty } } @Override protected void setUp() throws Exception { super.setUp(); accountVerification = new AccountVerificationMock(); stanzaRelay = new DeliveringInternalInboundStanzaRelay(EntityImpl.parse("vysper.org"), resourceRegistry, accountVerification, null); } public void testSimpleRelay() throws EntityFormatException, XMLSemanticError, DeliveryException { DefaultServerRuntimeContext serverRuntimeContext = new DefaultServerRuntimeContext(null, null); stanzaRelay.setServerRuntimeContext(serverRuntimeContext); TestSessionContext sessionContext = TestSessionContext.createSessionContext(TO_ENTITY); sessionContext.setSessionState(SessionState.AUTHENTICATED); resourceRegistry.bindSession(sessionContext); Stanza stanza = StanzaBuilder.createMessageStanza(FROM_ENTITY, TO_ENTITY, "en", "Hello").build(); try { stanzaRelay.relay(TO_ENTITY, stanza, new IgnoreFailureStrategy()); Stanza recordedStanza = sessionContext.getNextRecordedResponse(1000); assertNotNull("stanza delivered", recordedStanza); assertEquals("Hello", recordedStanza.getSingleInnerElementsNamed("body").getSingleInnerText().getText()); } catch (DeliveryException e) { throw e; } } public void testSimpleRelayToUnboundSession() throws EntityFormatException, XMLSemanticError, DeliveryException { TestSessionContext sessionContext = TestSessionContext.createSessionContext(TO_ENTITY); String resource = resourceRegistry.bindSession(sessionContext); boolean noResourceRemains = resourceRegistry.unbindResource(resource); assertTrue(noResourceRemains); Stanza stanza = StanzaBuilder.createMessageStanza(FROM_ENTITY, TO_ENTITY, "en", "Hello").build(); try { stanzaRelay.relay(TO_ENTITY, stanza, new IgnoreFailureStrategy()); Stanza recordedStanza = sessionContext.getNextRecordedResponse(1000); assertNull("stanza not delivered to unbound", recordedStanza); } catch (DeliveryException e) { throw e; } } public void testRelayToTwoRecepients_DeliverToALL() throws EntityFormatException, XMLSemanticError, DeliveryException, BindException { DefaultServerRuntimeContext serverRuntimeContext = new DefaultServerRuntimeContext(null, null); // !! DeliverMessageToHighestPriorityResourcesOnly = FALSE serverRuntimeContext.getServerFeatures().setDeliverMessageToHighestPriorityResourcesOnly(false); stanzaRelay.setServerRuntimeContext(serverRuntimeContext); TestSessionContext sessionContextTO_ENTITY_1_prio3 = createSessionForTo(TO_ENTITY, 3); // NON-NEGATIVE TestSessionContext sessionContextTO_ENTITY_2_prio0 = createSessionForTo(TO_ENTITY, 0); // NON-NEGATIVE TestSessionContext sessionContextTO_ENTITY_3_prio3 = createSessionForTo(TO_ENTITY, 3); // NON-NEGATIVE TestSessionContext sessionContextTO_ENTITY_4_prioMinus = createSessionForTo(TO_ENTITY, -1); // not receiving, negative Stanza stanza = StanzaBuilder.createMessageStanza(FROM_ENTITY, TO_ENTITY, "en", "Hello").build(); try { stanzaRelay.relay(TO_ENTITY, stanza, new IgnoreFailureStrategy()); Stanza recordedStanza_1 = sessionContextTO_ENTITY_1_prio3.getNextRecordedResponse(100); assertNotNull("stanza 1 delivered", recordedStanza_1); Stanza recordedStanza_2 = sessionContextTO_ENTITY_2_prio0.getNextRecordedResponse(100); assertNotNull("stanza 2 delivered", recordedStanza_2); Stanza recordedStanza_3 = sessionContextTO_ENTITY_3_prio3.getNextRecordedResponse(100); assertNotNull("stanza 3 delivered", recordedStanza_3); Stanza recordedStanza_4 = sessionContextTO_ENTITY_4_prioMinus.getNextRecordedResponse(100); assertNull("stanza 4 delivered", recordedStanza_4); } catch (DeliveryException e) { throw e; } } public void testRelayToTwoRecepients_DeliverToHIGHEST() throws EntityFormatException, XMLSemanticError, DeliveryException, BindException { DefaultServerRuntimeContext serverRuntimeContext = new DefaultServerRuntimeContext(null, null); // !! DeliverMessageToHighestPriorityResourcesOnly = TRUE serverRuntimeContext.getServerFeatures().setDeliverMessageToHighestPriorityResourcesOnly(true); stanzaRelay.setServerRuntimeContext(serverRuntimeContext); TestSessionContext sessionContextTO_ENTITY_1_prio3 = createSessionForTo(TO_ENTITY, 3); // HIGHEST PRIO TestSessionContext sessionContextTO_ENTITY_2_prio0 = createSessionForTo(TO_ENTITY, 1); // not receiving TestSessionContext sessionContextTO_ENTITY_3_prio3 = createSessionForTo(TO_ENTITY, 3); // HIGHEST PRIO TestSessionContext sessionContextTO_ENTITY_4_prioMinus = createSessionForTo(TO_ENTITY, -1); // not receiving Stanza stanza = StanzaBuilder.createMessageStanza(FROM_ENTITY, TO_ENTITY, "en", "Hello").build(); try { stanzaRelay.relay(TO_ENTITY, stanza, new IgnoreFailureStrategy()); Stanza recordedStanza_1 = sessionContextTO_ENTITY_1_prio3.getNextRecordedResponse(100); assertNotNull("stanza 1 delivered", recordedStanza_1); Stanza recordedStanza_2 = sessionContextTO_ENTITY_2_prio0.getNextRecordedResponse(100); assertNull("stanza 2 not delivered", recordedStanza_2); Stanza recordedStanza_3 = sessionContextTO_ENTITY_3_prio3.getNextRecordedResponse(100); assertNotNull("stanza 3 delivered", recordedStanza_3); Stanza recordedStanza_4 = sessionContextTO_ENTITY_4_prioMinus.getNextRecordedResponse(100); assertNull("stanza 4 not delivered", recordedStanza_4); } catch (DeliveryException e) { throw e; } } private TestSessionContext createSessionForTo(EntityImpl TO_ENTITY, final int priority) { TestSessionContext sessionContextTO_ENTITY = TestSessionContext.createSessionContext(TO_ENTITY); sessionContextTO_ENTITY.setSessionState(SessionState.AUTHENTICATED); String TO_ENTITYRes = resourceRegistry.bindSession(sessionContextTO_ENTITY); resourceRegistry.setResourcePriority(TO_ENTITYRes, priority); return sessionContextTO_ENTITY; } public void testShutdown() throws DeliveryException { final ExecutorService testExecutorService = Executors.newFixedThreadPool(1); DeliveringInternalInboundStanzaRelay relay = new DeliveringInternalInboundStanzaRelay(testExecutorService); Assert.assertTrue(relay.isRelaying()); relay.stop(); Assert.assertFalse(relay.isRelaying()); Assert.assertTrue(testExecutorService.isShutdown()); Stanza stanza = StanzaBuilder.createMessageStanza(FROM_ENTITY, TO_ENTITY, "en", "Hello").build(); try { relay.relay(TO_ENTITY, stanza, null); Assert.fail("ServiceNotAvailableException expected"); } catch (ServiceNotAvailableException e) { // test succeeds } } }