diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..26e468f33 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,7 @@ +Thank you for your contribution! + +Before creating a Pull Request, please make sure to +* read https://github.com/igniterealtime/Smack/wiki/Guidelines-for-Smack-Developers-and-Contributors +* run `gradle check` successfully in order to make sure that your code does not break any JUnit tests and is conform to the projects code style. +* (if applicable) mention any Jira issue codes (eg. `SMACK-XXX`) in the *body* of your commit message (not the header), so that Jira automatically links the PR to the issue. +* squash your commits if possible/sensible. diff --git a/documentation/developer/integrationtest.md b/documentation/developer/integrationtest.md index fc6684a3e..2bf2143db 100644 --- a/documentation/developer/integrationtest.md +++ b/documentation/developer/integrationtest.md @@ -80,6 +80,7 @@ debugger=console ### Where to place the properties file The framework will first load the properties file from `~/.config/smack-integration-test/properties` + Overview of the components -------------------------- diff --git a/smack-bosh/build.gradle b/smack-bosh/build.gradle index a3416325e..f686c8209 100644 --- a/smack-bosh/build.gradle +++ b/smack-bosh/build.gradle @@ -4,5 +4,7 @@ This API is considered beta quality.""" dependencies { compile project(':smack-core') - compile 'org.igniterealtime.jbosh:jbosh:[0.9,0.10)' + // See https://issues.igniterealtime.org/browse/SMACK-858 and + // comment in version.gradle why the specify the version this way. + compile 'org.igniterealtime.jbosh:jbosh:[0.9.1,0.9.999]' } diff --git a/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/BOSHConfiguration.java b/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/BOSHConfiguration.java index a83819ad2..8cf01fe85 100644 --- a/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/BOSHConfiguration.java +++ b/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/BOSHConfiguration.java @@ -19,6 +19,8 @@ package org.jivesoftware.smack.bosh; import java.net.URI; import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.proxy.ProxyInfo; @@ -34,6 +36,7 @@ public final class BOSHConfiguration extends ConnectionConfiguration { private final boolean https; private final String file; + private Map httpHeaders; private BOSHConfiguration(Builder builder) { super(builder); @@ -49,6 +52,7 @@ public final class BOSHConfiguration extends ConnectionConfiguration { } else { file = builder.file; } + httpHeaders = builder.httpHeaders; } public boolean isProxyEnabled() { @@ -76,6 +80,10 @@ public final class BOSHConfiguration extends ConnectionConfiguration { return new URI((https ? "https://" : "http://") + this.host + ":" + this.port + file); } + public Map getHttpHeaders() { + return httpHeaders; + } + public static Builder builder() { return new Builder(); } @@ -83,6 +91,7 @@ public final class BOSHConfiguration extends ConnectionConfiguration { public static final class Builder extends ConnectionConfiguration.Builder { private boolean https; private String file; + private Map httpHeaders = new HashMap<>(); private Builder() { } @@ -101,6 +110,11 @@ public final class BOSHConfiguration extends ConnectionConfiguration { return this; } + public Builder addHttpHeader(String name, String value) { + httpHeaders.put(name, value); + return this; + } + @Override public BOSHConfiguration build() { return new BOSHConfiguration(this); diff --git a/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java b/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java index 4270ffdee..7e1d97122 100644 --- a/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java +++ b/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java @@ -22,6 +22,7 @@ import java.io.PipedReader; import java.io.PipedWriter; import java.io.StringReader; import java.io.Writer; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -157,8 +158,13 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection { if (config.isProxyEnabled()) { cfgBuilder.setProxy(config.getProxyAddress(), config.getProxyPort()); } + cfgBuilder.setCompressionEnabled(config.isCompressionEnabled()); + for (Map.Entry h : config.getHttpHeaders().entrySet()) { + cfgBuilder.addHttpHeader(h.getKey(), h.getValue()); + } + client = BOSHClient.create(cfgBuilder.build()); client.addBOSHClientConnListener(new BOSHConnectionListener()); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index 53236e6b1..49b1e516f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -858,9 +858,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { ASYNC_BUT_ORDERED.performAsyncButOrdered(this, () -> { currentConnectionException = exception; - synchronized (AbstractXMPPConnection.this) { - notifyAll(); - } for (StanzaCollector collector : collectors) { collector.notifyConnectionError(exception); @@ -873,10 +870,14 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // XMPPTCPConnection. Create delegation method? // maybeCompressFeaturesReceived.reportGenericFailure(smackWrappedException); - // Closes the connection temporary. A if the connection supports stream management, then a reconnection is - // possible. Note that a connection listener of e.g. XMPPTCPConnection will drop the SM state in - // case the Exception is a StreamErrorException. - instantShutdown(); + synchronized (AbstractXMPPConnection.this) { + notifyAll(); + + // Closes the connection temporary. A if the connection supports stream management, then a reconnection is + // possible. Note that a connection listener of e.g. XMPPTCPConnection will drop the SM state in + // case the Exception is a StreamErrorException. + instantShutdown(); + } Async.go(() -> { // Notify connection listeners of the error. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/proxy/HTTPProxySocketConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/proxy/HTTPProxySocketConnection.java index cd1000c15..549406423 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/proxy/HTTPProxySocketConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/proxy/HTTPProxySocketConnection.java @@ -58,7 +58,7 @@ class HTTPProxySocketConnection implements ProxySocketConnection { proxyLine = "\r\nProxy-Authorization: Basic " + Base64.encode(username + ":" + password); } socket.getOutputStream().write((hostport + " HTTP/1.1\r\nHost: " - + hostport + proxyLine + "\r\n\r\n").getBytes("UTF-8")); + + host + ":" + port + proxyLine + "\r\n\r\n").getBytes("UTF-8")); InputStream in = socket.getInputStream(); StringBuilder got = new StringBuilder(100); @@ -115,7 +115,8 @@ class HTTPProxySocketConnection implements ProxySocketConnection { int code = Integer.parseInt(m.group(1)); if (code != HttpURLConnection.HTTP_OK) { - throw new ProxyException(ProxyInfo.ProxyType.HTTP); + throw new ProxyException(ProxyInfo.ProxyType.HTTP, + "Error code in proxy response: " + code); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java index 98e3dfdc0..639e2f792 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java @@ -152,8 +152,11 @@ public final class MultiUserChatManager extends Manager { private AutoJoinFailedCallback autoJoinFailedCallback; + private final ServiceDiscoveryManager serviceDiscoveryManager; + private MultiUserChatManager(XMPPConnection connection) { super(connection); + serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); // Listens for all messages that include a MUCUser extension and fire the invitation // listeners if the message includes an invitation. StanzaListener invitationPacketListener = new StanzaListener() { @@ -277,7 +280,7 @@ public final class MultiUserChatManager extends Manager { * @throws InterruptedException */ public boolean isServiceEnabled(Jid user) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(user, MUCInitialPresence.NAMESPACE); + return serviceDiscoveryManager.supportsFeature(user, MUCInitialPresence.NAMESPACE); } /** @@ -304,7 +307,7 @@ public final class MultiUserChatManager extends Manager { public List getJoinedRooms(EntityJid user) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { // Send the disco packet to the user - DiscoverItems result = ServiceDiscoveryManager.getInstanceFor(connection()).discoverItems(user, DISCO_NODE); + DiscoverItems result = serviceDiscoveryManager.discoverItems(user, DISCO_NODE); List items = result.getItems(); List answer = new ArrayList<>(items.size()); // Collect the entityID for each returned item @@ -331,7 +334,7 @@ public final class MultiUserChatManager extends Manager { * @throws InterruptedException */ public RoomInfo getRoomInfo(EntityBareJid room) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection()).discoverInfo(room); + DiscoverInfo info = serviceDiscoveryManager.discoverInfo(room); return new RoomInfo(info); } @@ -345,8 +348,7 @@ public final class MultiUserChatManager extends Manager { * @throws InterruptedException */ public List getMucServiceDomains() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection()); - return sdm.findServices(MUCInitialPresence.NAMESPACE, false, false); + return serviceDiscoveryManager.findServices(MUCInitialPresence.NAMESPACE, false, false); } /** @@ -379,7 +381,7 @@ public final class MultiUserChatManager extends Manager { */ public boolean providesMucService(DomainBareJid domainBareJid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(domainBareJid, + return serviceDiscoveryManager.supportsFeature(domainBareJid, MUCInitialPresence.NAMESPACE); } @@ -402,8 +404,7 @@ public final class MultiUserChatManager extends Manager { if (!providesMucService(serviceName)) { throw new NotAMucServiceException(serviceName); } - ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection()); - DiscoverItems discoverItems = discoManager.discoverItems(serviceName); + DiscoverItems discoverItems = serviceDiscoveryManager.discoverItems(serviceName); List items = discoverItems.getItems(); Map answer = new HashMap<>(items.size()); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java index 76e89369a..89d4b5bb3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java @@ -447,6 +447,19 @@ public final class PingManager extends Manager { pingFuture.onError(new ExceptionCallback() { @Override public void processException(Exception exception) { + long lastStanzaReceived = connection.getLastStanzaReceived(); + if (lastStanzaReceived > 0) { + long now = System.currentTimeMillis(); + // Delta since the last stanza was received + int deltaInSeconds = (int) ((now - lastStanzaReceived) / 1000); + // If the delta is smaller then the ping interval, we have got an valid stanza in time + // So not error notification needed + if (deltaInSeconds < pingInterval) { + maybeSchedulePingServerTask(deltaInSeconds); + return; + } + } + for (PingFailedListener l : pingFailedListeners) { l.pingFailed(); } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index 8e241151d..e9652e652 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2016-2017 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2016-2019 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -629,14 +629,40 @@ public final class Roster extends Manager { * @throws NotLoggedInException If not logged in. * @throws NotConnectedException * @throws InterruptedException + * @deprecated use {@link #createItemAndRequestSubscription(BareJid, String, String[])} instead. */ + // TODO: Remove in Smack 4.5. + @Deprecated public void createEntry(BareJid user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + createItemAndRequestSubscription(user, name, groups); + } + + /** + * Creates a new roster item. The server will asynchronously update the roster with the subscription status. + *

+ * There will be no presence subscription request. Consider using + * {@link #createItemAndRequestSubscription(BareJid, String, String[])} if you also want to request a presence + * subscription from the contact. + *

+ * + * @param jid the XMPP address of the contact (e.g. johndoe@jabber.org) + * @param name the nickname of the user. + * @param groups the list of group names the entry will belong to, or null if the the roster entry won't + * belong to a group. + * @throws NoResponseException if there was no response from the server. + * @throws XMPPErrorException if an XMPP exception occurs. + * @throws NotLoggedInException If not logged in. + * @throws NotConnectedException + * @throws InterruptedException + * @since 4.4.0 + */ + public void createItem(BareJid jid, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { final XMPPConnection connection = getAuthenticatedConnectionOrThrow(); // Create and send roster entry creation packet. RosterPacket rosterPacket = new RosterPacket(); rosterPacket.setType(IQ.Type.set); - RosterPacket.Item item = new RosterPacket.Item(user, name); + RosterPacket.Item item = new RosterPacket.Item(jid, name); if (groups != null) { for (String group : groups) { if (group != null && group.trim().length() > 0) { @@ -646,8 +672,27 @@ public final class Roster extends Manager { } rosterPacket.addRosterItem(item); connection.createStanzaCollectorAndSend(rosterPacket).nextResultOrThrow(); + } - sendSubscriptionRequest(user); + /** + * Creates a new roster entry and presence subscription. The server will asynchronously + * update the roster with the subscription status. + * + * @param jid the XMPP address of the contact (e.g. johndoe@jabber.org) + * @param name the nickname of the user. + * @param groups the list of group names the entry will belong to, or null if the + * the roster entry won't belong to a group. + * @throws NoResponseException if there was no response from the server. + * @throws XMPPErrorException if an XMPP exception occurs. + * @throws NotLoggedInException If not logged in. + * @throws NotConnectedException + * @throws InterruptedException + * @since 4.4.0 + */ + public void createItemAndRequestSubscription(BareJid jid, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + createItem(jid, name, groups); + + sendSubscriptionRequest(jid); } /** @@ -668,7 +713,7 @@ public final class Roster extends Manager { */ public void preApproveAndCreateEntry(BareJid user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, FeatureNotSupportedException { preApprove(user); - createEntry(user, name, groups); + createItemAndRequestSubscription(user, name, groups); } /** diff --git a/smack-im/src/test/java/org/jivesoftware/smack/roster/RosterTest.java b/smack-im/src/test/java/org/jivesoftware/smack/roster/RosterTest.java index 4d26b20c6..85d0457d6 100644 --- a/smack-im/src/test/java/org/jivesoftware/smack/roster/RosterTest.java +++ b/smack-im/src/test/java/org/jivesoftware/smack/roster/RosterTest.java @@ -164,7 +164,7 @@ public class RosterTest extends InitSmackIm { } }; serverSimulator.start(); - roster.createEntry(contactJID, contactName, contactGroup); + roster.createItemAndRequestSubscription(contactJID, contactName, contactGroup); serverSimulator.join(); // Check if an error occurred within the simulator @@ -430,7 +430,7 @@ public class RosterTest extends InitSmackIm { } }; serverSimulator.start(); - roster.createEntry(contactJID, contactName, contactGroup); + roster.createItemAndRequestSubscription(contactJID, contactName, contactGroup); serverSimulator.join(); // Check if an error occurred within the simulator diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index 8cabed30c..acb62b869 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -299,10 +299,32 @@ public class XmppConnectionStressTest { private ErrorsWhileSendingOrReceivingException(Map sendExceptions, Map receiveExceptions) { - super("Exceptions while sending and/or receiving"); + super(createMessageFrom(sendExceptions, receiveExceptions)); this.sendExceptions = sendExceptions; this.receiveExceptions = receiveExceptions; } + + private static String createMessageFrom(Map sendExceptions, + Map receiveExceptions) { + StringBuilder sb = new StringBuilder(1024); + sb.append("Exceptions while sending and/or receiving."); + + if (!sendExceptions.isEmpty()) { + sb.append(" Send exxceptions: "); + for (Map.Entry entry : sendExceptions.entrySet()) { + sb.append(entry.getKey()).append(": ").append(entry.getValue()).append(';'); + } + } + + if (!receiveExceptions.isEmpty()) { + sb.append(" Receive exceptions: "); + for (Map.Entry entry : receiveExceptions.entrySet()) { + sb.append(entry.getKey()).append(": ").append(entry.getValue()); + } + } + + return sb.toString(); + } } } } diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/IntegrationTestRosterUtil.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/IntegrationTestRosterUtil.java index 11a0d7b59..c03ba1850 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/IntegrationTestRosterUtil.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/util/IntegrationTestRosterUtil.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2018 Florian Schmaus + * Copyright 2015-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,11 +25,13 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.roster.AbstractPresenceEventListener; +import org.jivesoftware.smack.roster.PresenceEventListener; import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smack.roster.RosterEntry; import org.jivesoftware.smack.roster.SubscribeListener; import org.jxmpp.jid.BareJid; +import org.jxmpp.jid.EntityFullJid; import org.jxmpp.jid.Jid; public class IntegrationTestRosterUtil { @@ -39,41 +41,47 @@ public class IntegrationTestRosterUtil { ensureSubscribedTo(conTwo, conOne, timeout); } - public static void ensureSubscribedTo(final XMPPConnection conOne, final XMPPConnection conTwo, long timeout) throws TimeoutException, Exception { - Roster rosterOne = Roster.getInstanceFor(conOne); - Roster rosterTwo = Roster.getInstanceFor(conTwo); + public static void ensureSubscribedTo(final XMPPConnection presenceRequestReceiverConnection, final XMPPConnection presenceRequestingConnection, long timeout) throws TimeoutException, Exception { + final Roster presenceRequestReceiverRoster = Roster.getInstanceFor(presenceRequestReceiverConnection); + final Roster presenceRequestingRoster = Roster.getInstanceFor(presenceRequestingConnection); - if (rosterOne.isSubscribedToMyPresence(conTwo.getUser())) { + final EntityFullJid presenceRequestReceiverAddress = presenceRequestReceiverConnection.getUser(); + final EntityFullJid presenceRequestingAddress = presenceRequestingConnection.getUser(); + + if (presenceRequestReceiverRoster.isSubscribedToMyPresence(presenceRequestingAddress)) { return; } final SubscribeListener subscribeListener = new SubscribeListener() { @Override public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) { - if (from.equals(conTwo.getUser().asBareJid())) { + if (from.equals(presenceRequestingConnection.getUser().asBareJid())) { return SubscribeAnswer.Approve; } return SubscribeAnswer.Deny; } }; - rosterOne.addSubscribeListener(subscribeListener); + presenceRequestReceiverRoster.addSubscribeListener(subscribeListener); final SimpleResultSyncPoint syncPoint = new SimpleResultSyncPoint(); - rosterTwo.addPresenceEventListener(new AbstractPresenceEventListener() { + final PresenceEventListener presenceEventListener = new AbstractPresenceEventListener() { @Override public void presenceSubscribed(BareJid address, Presence subscribedPresence) { - if (!address.equals(conOne.getUser().asBareJid())) { + if (!address.equals(presenceRequestReceiverAddress.asBareJid())) { return; } syncPoint.signal(); } - }); - rosterTwo.sendSubscriptionRequest(conOne.getUser().asBareJid()); + }; + presenceRequestingRoster.addPresenceEventListener(presenceEventListener); try { + presenceRequestingRoster.sendSubscriptionRequest(presenceRequestReceiverAddress.asBareJid()); + syncPoint.waitForResult(timeout); } finally { - rosterOne.removeSubscribeListener(subscribeListener); + presenceRequestReceiverRoster.removeSubscribeListener(subscribeListener); + presenceRequestingRoster.removePresenceEventListener(presenceEventListener); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java index fac15a6dc..242491c96 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/LowLevelRosterIntegrationTest.java @@ -42,12 +42,9 @@ public class LowLevelRosterIntegrationTest extends AbstractSmackLowLevelIntegrat final Roster rosterOne = Roster.getInstanceFor(conOne); final Roster rosterTwo = Roster.getInstanceFor(conTwo); - // TODO create Roster.createEntry() with boolean flag for subscribe or not. - rosterOne.createEntry(conTwo.getUser().asBareJid(), "Con Two", null); - rosterTwo.createEntry(conOne.getUser().asBareJid(), "Con One", null); + rosterOne.createItem(conTwo.getUser().asBareJid(), "Con Two", null); + rosterTwo.createItem(conOne.getUser().asBareJid(), "Con One", null); - // TODO Change timeout form '5000' to something configurable. - final long timeout = 5000; IntegrationTestRosterUtil.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout); final SimpleResultSyncPoint offlineTriggered = new SimpleResultSyncPoint(); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java index 77bd1d8bb..beff7eb1b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java @@ -99,7 +99,7 @@ public class RosterIntegrationTest extends AbstractSmackIntegrationTest { }); try { - rosterOne.createEntry(conTwo.getUser().asBareJid(), conTwosRosterName, null); + rosterOne.createItemAndRequestSubscription(conTwo.getUser().asBareJid(), conTwosRosterName, null); assertTrue(addedAndSubscribed.waitForResult(2 * connection.getReplyTimeout())); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java index e75693108..902c2b97f 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mood/MoodIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2018 Paul Schaub. + * Copyright 2018 Paul Schaub, 2019 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,6 @@ package org.jivesoftware.smackx.mood; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.packet.Message; - -import org.jivesoftware.smackx.mood.element.MoodElement; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTest; @@ -28,7 +25,6 @@ import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.junit.AfterClass; -import org.jxmpp.jid.BareJid; public class MoodIntegrationTest extends AbstractSmackIntegrationTest { @@ -47,18 +43,20 @@ public class MoodIntegrationTest extends AbstractSmackIntegrationTest { final SimpleResultSyncPoint moodReceived = new SimpleResultSyncPoint(); - mm2.addMoodListener(new MoodListener() { - @Override - public void onMoodUpdated(BareJid jid, Message message, MoodElement moodElement) { - if (moodElement.getMood() == Mood.satisfied) { - moodReceived.signal(); - } + final MoodListener moodListener = (jid, message, moodElement) -> { + if (moodElement.getMood() == Mood.satisfied) { + moodReceived.signal(); } - }); + }; + mm2.addMoodListener(moodListener); - mm1.setMood(Mood.satisfied); + try { + mm1.setMood(Mood.satisfied); - moodReceived.waitForResult(timeout); + moodReceived.waitForResult(timeout); + } finally { + mm2.removeMoodListener(moodListener); + } } @AfterClass diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 68b1fe8a0..183275771 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -609,6 +609,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { proxyInfo.getProxySocketConnection().connect(socket, host, port, timeout); } catch (IOException e) { hostAddress.setException(e); + failedAddresses.add(hostAddress); continue; } LOGGER.finer("Established TCP connection to " + hostAndPort);