Search in sources :

Example 26 with AndFilter

use of org.jivesoftware.smack.filter.AndFilter in project Smack by igniterealtime.

the class XmppConnectionStressTest method run.

public void run(List<? extends XMPPConnection> connections, final long replyTimeoutMillis) throws InterruptedException, NotAllMessagesReceivedException, ErrorsWhileSendingOrReceivingException {
    final MultiMap<XMPPConnection, Message> messages = new MultiMap<>();
    final Random random = new Random(configuration.seed);
    final Map<XMPPConnection, Exception> sendExceptions = new ConcurrentHashMap<>();
    final Map<XMPPConnection, Exception> receiveExceptions = new ConcurrentHashMap<>();
    waitStart = -1;
    for (XMPPConnection fromConnection : connections) {
        MultiMap<XMPPConnection, Message> toConnectionMessages = new MultiMap<>();
        for (XMPPConnection toConnection : connections) {
            for (int i = 0; i < configuration.messagesPerConnection; i++) {
                MessageBuilder messageBuilder = fromConnection.getStanzaFactory().buildMessageStanza();
                messageBuilder.to(toConnection.getUser());
                final int payloadChunkCount;
                if (configuration.maxPayloadChunks == 0) {
                    payloadChunkCount = 0;
                } else {
                    payloadChunkCount = random.nextInt(configuration.maxPayloadChunks) + 1;
                }
                for (int c = 0; c < payloadChunkCount; c++) {
                    int payloadChunkSize = random.nextInt(configuration.maxPayloadChunkSize) + 1;
                    String payloadCunk = StringUtils.randomString(payloadChunkSize, random);
                    JivePropertiesManager.addProperty(messageBuilder, "payload-chunk-" + c, payloadCunk);
                }
                JivePropertiesManager.addProperty(messageBuilder, MESSAGE_NUMBER_PROPERTY, i);
                Message message = messageBuilder.build();
                toConnectionMessages.put(toConnection, message);
            }
        }
        if (configuration.intermixMessages) {
            while (!toConnectionMessages.isEmpty()) {
                int next = random.nextInt(connections.size());
                Message message = null;
                while (message == null) {
                    XMPPConnection toConnection = connections.get(next);
                    message = toConnectionMessages.getFirst(toConnection);
                    next = (next + 1) % connections.size();
                }
                messages.put(fromConnection, message);
            }
        } else {
            for (XMPPConnection toConnection : connections) {
                for (Message message : toConnectionMessages.getAll(toConnection)) {
                    messages.put(fromConnection, message);
                }
            }
        }
    }
    Semaphore receivedSemaphore = new Semaphore(-connections.size() + 1);
    Map<XMPPConnection, Map<EntityFullJid, boolean[]>> receiveMarkers = new ConcurrentHashMap<>(connections.size());
    for (XMPPConnection connection : connections) {
        final Map<EntityFullJid, boolean[]> myReceiveMarkers = new HashMap<>(connections.size());
        receiveMarkers.put(connection, myReceiveMarkers);
        for (XMPPConnection otherConnection : connections) {
            boolean[] fromMarkers = new boolean[configuration.messagesPerConnection];
            myReceiveMarkers.put(otherConnection.getUser(), fromMarkers);
        }
        connection.addSyncStanzaListener(new StanzaListener() {

            @Override
            public void processStanza(Stanza stanza) {
                waitStart = System.currentTimeMillis();
                EntityFullJid from = stanza.getFrom().asEntityFullJidOrThrow();
                Message message = (Message) stanza;
                JivePropertiesExtension extension = JivePropertiesExtension.from(message);
                Integer messageNumber = (Integer) extension.getProperty(MESSAGE_NUMBER_PROPERTY);
                boolean[] fromMarkers = myReceiveMarkers.get(from);
                // Sanity check: All markers before must be true, all markers including the messageNumber marker must be false.
                for (int i = 0; i < fromMarkers.length; i++) {
                    final String inOrderViolation;
                    if (i < messageNumber && !fromMarkers[i]) {
                        // A previous message was missing.
                        inOrderViolation = "not yet message #";
                    } else if (i >= messageNumber && fromMarkers[i]) {
                        // We already received a new message.
                        // TODO: Can it ever happen that this is taken? Wouldn't we prior run into the "a previous
                        // message is missing" case?
                        inOrderViolation = "we already received a later (or the same) message #";
                    } else {
                        continue;
                    }
                    StringBuilder exceptionMessage = new StringBuilder();
                    exceptionMessage.append("We received message #").append(messageNumber).append(" but ");
                    exceptionMessage.append(inOrderViolation);
                    exceptionMessage.append(i);
                    exceptionMessage.append("\nMessage with id ").append(stanza.getStanzaId()).append(" from ").append(from).append(" to ").append(stanza.getTo()).append('\n');
                    exceptionMessage.append("From Markers: ").append(Arrays.toString(fromMarkers)).append('\n');
                    Exception exception = new Exception(exceptionMessage.toString());
                    receiveExceptions.put(connection, exception);
                    // TODO: Current Smack design does not guarantee that the listener won't be invoked again.
                    // This is because the decission to invoke a sync listeners is done at a different place
                    // then invoking the listener.
                    connection.removeSyncStanzaListener(this);
                    receivedSemaphore.release();
                    // TODO: Do not return here?
                    return;
                }
                fromMarkers[messageNumber] = true;
                for (boolean[] markers : myReceiveMarkers.values()) {
                    if (BooleansUtils.contains(markers, false)) {
                        // receivedSemaphore.
                        return;
                    }
                }
                // All markers set to true, this means we received all messages.
                receivedSemaphore.release();
            }
        }, new AndFilter(MessageTypeFilter.NORMAL, new StanzaExtensionFilter(JivePropertiesExtension.ELEMENT, JivePropertiesExtension.NAMESPACE)));
    }
    Semaphore sendSemaphore = new Semaphore(-connections.size() + 1);
    for (XMPPConnection connection : connections) {
        Async.go(() -> {
            List<Message> messagesToSend;
            synchronized (messages) {
                messagesToSend = messages.getAll(connection);
            }
            try {
                for (Message messageToSend : messagesToSend) {
                    connection.sendStanza(messageToSend);
                }
            } catch (NotConnectedException | InterruptedException e) {
                sendExceptions.put(connection, e);
            } finally {
                sendSemaphore.release();
            }
        });
    }
    sendSemaphore.acquire();
    if (waitStart < 0) {
        waitStart = System.currentTimeMillis();
    }
    boolean acquired;
    do {
        long acquireWait = waitStart + replyTimeoutMillis - System.currentTimeMillis();
        acquired = receivedSemaphore.tryAcquire(acquireWait, TimeUnit.MILLISECONDS);
    } while (!acquired && System.currentTimeMillis() < waitStart + replyTimeoutMillis);
    if (!acquired && receiveExceptions.isEmpty() && sendExceptions.isEmpty()) {
        throw new StressTestFailedException.NotAllMessagesReceivedException(receiveMarkers, connections);
    }
    if (!receiveExceptions.isEmpty() || !sendExceptions.isEmpty()) {
        throw new StressTestFailedException.ErrorsWhileSendingOrReceivingException(sendExceptions, receiveExceptions);
    }
// Test successful.
}
Also used : Message(org.jivesoftware.smack.packet.Message) NotConnectedException(org.jivesoftware.smack.SmackException.NotConnectedException) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) StanzaExtensionFilter(org.jivesoftware.smack.filter.StanzaExtensionFilter) StanzaListener(org.jivesoftware.smack.StanzaListener) XMPPConnection(org.jivesoftware.smack.XMPPConnection) Semaphore(java.util.concurrent.Semaphore) MultiMap(org.jivesoftware.smack.util.MultiMap) Random(java.util.Random) MessageBuilder(org.jivesoftware.smack.packet.MessageBuilder) NotAllMessagesReceivedException(org.igniterealtime.smack.XmppConnectionStressTest.StressTestFailedException.NotAllMessagesReceivedException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) EntityFullJid(org.jxmpp.jid.EntityFullJid) Stanza(org.jivesoftware.smack.packet.Stanza) NotConnectedException(org.jivesoftware.smack.SmackException.NotConnectedException) NotAllMessagesReceivedException(org.igniterealtime.smack.XmppConnectionStressTest.StressTestFailedException.NotAllMessagesReceivedException) ErrorsWhileSendingOrReceivingException(org.igniterealtime.smack.XmppConnectionStressTest.StressTestFailedException.ErrorsWhileSendingOrReceivingException) JivePropertiesExtension(org.jivesoftware.smackx.jiveproperties.packet.JivePropertiesExtension) AndFilter(org.jivesoftware.smack.filter.AndFilter) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MultiMap(org.jivesoftware.smack.util.MultiMap) ErrorsWhileSendingOrReceivingException(org.igniterealtime.smack.XmppConnectionStressTest.StressTestFailedException.ErrorsWhileSendingOrReceivingException)

Example 27 with AndFilter

use of org.jivesoftware.smack.filter.AndFilter in project Smack by igniterealtime.

the class EntityCapsTest method testEntityCaps.

@SmackIntegrationTest
public void testEntityCaps() throws XMPPException, InterruptedException, NoResponseException, NotConnectedException, TimeoutException {
    final String dummyFeature = getNewDummyFeature();
    dropWholeEntityCapsCache();
    performActionAndWaitUntilStanzaReceived(new Runnable() {

        @Override
        public void run() {
            sdmTwo.addFeature(dummyFeature);
        }
    }, connection, new AndFilter(PresenceTypeFilter.AVAILABLE, FromMatchesFilter.create(conTwo.getUser())));
    waitUntilTrue(new Condition() {

        @Override
        public boolean evaluate() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
            DiscoverInfo info = sdmOne.discoverInfo(conTwo.getUser());
            return info.containsFeature(dummyFeature);
        }
    });
    DiscoverInfo info = sdmOne.discoverInfo(conTwo.getUser());
    String u1ver = EntityCapsManager.getNodeVersionByJid(conTwo.getUser());
    assertNotNull(u1ver);
    DiscoverInfo entityInfo = EntityCapsManager.CAPS_CACHE.lookup(u1ver);
    assertNotNull(entityInfo);
    assertEquals(info.toXML().toString(), entityInfo.toXML().toString());
}
Also used : AndFilter(org.jivesoftware.smack.filter.AndFilter) DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo) XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException) NotConnectedException(org.jivesoftware.smack.SmackException.NotConnectedException) ThrowingRunnable(org.jivesoftware.smack.util.Async.ThrowingRunnable) NoResponseException(org.jivesoftware.smack.SmackException.NoResponseException) SmackIntegrationTest(org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest) AbstractSmackIntegrationTest(org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest)

Example 28 with AndFilter

use of org.jivesoftware.smack.filter.AndFilter in project Smack by igniterealtime.

the class EntityCapsTest method testLocalEntityCaps.

@SmackIntegrationTest
public void testLocalEntityCaps() throws InterruptedException, NoResponseException, XMPPErrorException, NotConnectedException {
    final String dummyFeature = getNewDummyFeature();
    DiscoverInfo info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecmTwo.getLocalNodeVer());
    assertFalse(info.containsFeature(dummyFeature));
    dropWholeEntityCapsCache();
    performActionAndWaitUntilStanzaReceived(new Runnable() {

        @Override
        public void run() {
            // This should cause a new presence stanza from con1 with and updated
            // 'ver' String
            sdmTwo.addFeature(dummyFeature);
        }
    }, conOne, new AndFilter(PresenceTypeFilter.AVAILABLE, FromMatchesFilter.create(conTwo.getUser())));
    // The presence stanza should get received by con0 and the data should
    // be recorded in the map
    // Note that while both connections use the same static Entity Caps
    // cache,
    // it's assured that *not* con1 added the data to the Entity Caps cache.
    // Every time the entities features
    // and identities change only a new caps 'ver' is calculated and send
    // with the presence stanza
    // The other connection has to receive this stanza and record the
    // information in order for this test to succeed.
    info = EntityCapsManager.getDiscoveryInfoByNodeVer(ecmTwo.getLocalNodeVer());
    assertNotNull(info);
    assertTrue(info.containsFeature(dummyFeature));
}
Also used : DiscoverInfo(org.jivesoftware.smackx.disco.packet.DiscoverInfo) AndFilter(org.jivesoftware.smack.filter.AndFilter) ThrowingRunnable(org.jivesoftware.smack.util.Async.ThrowingRunnable) SmackIntegrationTest(org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest) AbstractSmackIntegrationTest(org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest)

Example 29 with AndFilter

use of org.jivesoftware.smack.filter.AndFilter in project Smack by igniterealtime.

the class Workgroup method isAvailable.

/**
 * Returns true if the workgroup is available for receiving new requests. The workgroup will be
 * available only when agents are available for this workgroup.
 *
 * @return true if the workgroup is available for receiving new requests.
 * @throws XMPPErrorException if there was an XMPP error returned.
 * @throws NoResponseException if there was no response from the remote entity.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws InterruptedException if the calling thread was interrupted.
 */
public boolean isAvailable() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    Presence directedPresence = connection.getStanzaFactory().buildPresenceStanza().ofType(Presence.Type.available).to(workgroupJID).build();
    StanzaFilter typeFilter = new StanzaTypeFilter(Presence.class);
    StanzaFilter fromFilter = FromMatchesFilter.create(workgroupJID);
    StanzaCollector collector = connection.createStanzaCollectorAndSend(new AndFilter(fromFilter, typeFilter), directedPresence);
    Presence response = collector.nextResultOrThrow();
    return Presence.Type.available == response.getType();
}
Also used : StanzaTypeFilter(org.jivesoftware.smack.filter.StanzaTypeFilter) AndFilter(org.jivesoftware.smack.filter.AndFilter) StanzaFilter(org.jivesoftware.smack.filter.StanzaFilter) Presence(org.jivesoftware.smack.packet.Presence) StanzaCollector(org.jivesoftware.smack.StanzaCollector)

Example 30 with AndFilter

use of org.jivesoftware.smack.filter.AndFilter in project Smack by igniterealtime.

the class AgentSession method setStatus.

/**
 * Sets the agent's current status with the workgroup. The presence mode affects how offers
 * are routed to the agent. The possible presence modes with their meanings are as follows:<ul>
 *
 * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats
 * (equivalent to Presence.Mode.CHAT).
 * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed.
 * However, special case, or extreme urgency chats may still be offered to the agent.
 * <li>Presence.Mode.AWAY -- the agent is not available and should not
 * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul>
 *
 * @param presenceMode the presence mode of the agent.
 * @param status       sets the status message of the presence update.
 * @throws XMPPErrorException if there was an XMPP error returned.
 * @throws NoResponseException if there was no response from the remote entity.
 * @throws NotConnectedException if the XMPP connection is not connected.
 * @throws InterruptedException if the calling thread was interrupted.
 * @throws IllegalStateException if the agent is not online with the workgroup.
 */
public void setStatus(Presence.Mode presenceMode, String status) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    if (!online) {
        throw new IllegalStateException("Cannot set status when the agent is not online.");
    }
    if (presenceMode == null) {
        presenceMode = Presence.Mode.available;
    }
    this.presenceMode = presenceMode;
    PresenceBuilder presenceBuilder = connection.getStanzaFactory().buildPresenceStanza().ofType(Presence.Type.available).setMode(presenceMode).to(getWorkgroupJID());
    if (status != null) {
        presenceBuilder.setStatus(status);
    }
    Presence presence = presenceBuilder.build();
    presence.addExtension(new MetaData(this.metaData));
    StanzaCollector collector = this.connection.createStanzaCollectorAndSend(new AndFilter(new StanzaTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)), presence);
    collector.nextResultOrThrow();
}
Also used : AndFilter(org.jivesoftware.smack.filter.AndFilter) StanzaTypeFilter(org.jivesoftware.smack.filter.StanzaTypeFilter) MetaData(org.jivesoftware.smackx.workgroup.MetaData) PresenceBuilder(org.jivesoftware.smack.packet.PresenceBuilder) Presence(org.jivesoftware.smack.packet.Presence) StanzaCollector(org.jivesoftware.smack.StanzaCollector)

Aggregations

AndFilter (org.jivesoftware.smack.filter.AndFilter)34 PacketTypeFilter (org.jivesoftware.smack.filter.PacketTypeFilter)15 Presence (org.jivesoftware.smack.packet.Presence)15 PacketFilter (org.jivesoftware.smack.filter.PacketFilter)13 StanzaTypeFilter (org.jivesoftware.smack.filter.StanzaTypeFilter)9 StanzaCollector (org.jivesoftware.smack.StanzaCollector)8 Message (org.jivesoftware.smack.packet.Message)8 XMPPException (org.jivesoftware.smack.XMPPException)7 FromMatchesFilter (org.jivesoftware.smack.filter.FromMatchesFilter)7 PacketIDFilter (org.jivesoftware.smack.filter.PacketIDFilter)7 IQ (org.jivesoftware.smack.packet.IQ)7 StanzaFilter (org.jivesoftware.smack.filter.StanzaFilter)6 Registration (org.jivesoftware.smack.packet.Registration)6 PacketCollector (org.jivesoftware.smack.PacketCollector)5 Packet (org.jivesoftware.smack.packet.Packet)5 Stanza (org.jivesoftware.smack.packet.Stanza)5 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 SmackIntegrationTest (org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest)4 MUCInitialPresence (org.jivesoftware.smackx.packet.MUCInitialPresence)4