1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-06-16 08:34:50 +02:00

IntegrationTest for JingleIBBTransport

This commit is contained in:
vanitasvitae 2017-07-27 18:09:49 +02:00
parent 3ed3f53189
commit 68a03aeb48
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
7 changed files with 126 additions and 28 deletions

View file

@ -0,0 +1,13 @@
package org.jivesoftware.smackx.jingle.callbacks;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
/**
* Created by vanitas on 27.07.17.
*/
public interface JingleTransportCallback {
void onTransportReady(BytestreamSession bytestreamSession);
void onTransportFailed(Exception e);
}

View file

@ -32,6 +32,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.jingle.JingleManager; import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter; import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter; import org.jivesoftware.smackx.jingle.adapter.JingleTransportAdapter;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement; import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement; import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement; import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
@ -45,7 +46,7 @@ import org.jivesoftware.smackx.jingle.JingleTransportManager;
/** /**
* Internal class that holds the state of a content in a modifiable form. * Internal class that holds the state of a content in a modifiable form.
*/ */
public class JingleContent { public class JingleContent implements JingleTransportCallback {
private static final Logger LOGGER = Logger.getLogger(JingleContent.class.getName()); private static final Logger LOGGER = Logger.getLogger(JingleContent.class.getName());
@ -213,8 +214,8 @@ public class JingleContent {
getSenders() == JingleContentElement.Senders.both; getSenders() == JingleContentElement.Senders.both;
} }
public void onTransportReady() { @Override
BytestreamSession bytestreamSession = transport.getBytestreamSession(); public void onTransportReady(BytestreamSession bytestreamSession) {
if (bytestreamSession == null) { if (bytestreamSession == null) {
throw new AssertionError("bytestreamSession MUST NOT be null at this point."); throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
@ -223,6 +224,7 @@ public class JingleContent {
description.onTransportReady(bytestreamSession); description.onTransportReady(bytestreamSession);
} }
@Override
public void onTransportFailed(Exception e) { public void onTransportFailed(Exception e) {
//Add current transport to blacklist. //Add current transport to blacklist.
getTransportBlacklist().add(transport.getNamespace()); getTransportBlacklist().add(transport.getNamespace());
@ -264,9 +266,9 @@ public class JingleContent {
throws SmackException.NotConnectedException, InterruptedException { throws SmackException.NotConnectedException, InterruptedException {
//Establish transport //Establish transport
if (isReceiving()) { if (isReceiving()) {
getTransport().establishIncomingBytestreamSession(connection); getTransport().establishIncomingBytestreamSession(connection, this);
} else if (isSending()) { } else if (isSending()) {
getTransport().establishOutgoingBytestreamSession(connection); getTransport().establishOutgoingBytestreamSession(connection, this);
} }
} }

View file

@ -23,6 +23,7 @@ import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackFuture; import org.jivesoftware.smack.SmackFuture;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.bytestreams.BytestreamSession; import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement; import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement; import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement;
import org.jivesoftware.smackx.jingle.element.JingleElement; import org.jivesoftware.smackx.jingle.element.JingleElement;
@ -75,10 +76,10 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
public abstract String getNamespace(); public abstract String getNamespace();
public abstract void establishIncomingBytestreamSession(XMPPConnection connection) public abstract void establishIncomingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback)
throws SmackException.NotConnectedException, InterruptedException; throws SmackException.NotConnectedException, InterruptedException;
public abstract void establishOutgoingBytestreamSession(XMPPConnection connection) public abstract void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback)
throws SmackException.NotConnectedException, InterruptedException; throws SmackException.NotConnectedException, InterruptedException;
public void setPeersProposal(JingleTransport<?> peersProposal) { public void setPeersProposal(JingleTransport<?> peersProposal) {

View file

@ -25,11 +25,12 @@ import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamListener; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamListener;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement; import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.components.JingleSession; import org.jivesoftware.smackx.jingle.components.JingleSession;
import org.jivesoftware.smackx.jingle.components.JingleTransport; import org.jivesoftware.smackx.jingle.components.JingleTransport;
import org.jivesoftware.smackx.jingle.components.JingleTransportCandidate; import org.jivesoftware.smackx.jingle.components.JingleTransportCandidate;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement;
import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.transport.jingle_ibb.element.JingleIBBTransportElement; import org.jivesoftware.smackx.jingle.transport.jingle_ibb.element.JingleIBBTransportElement;
/** /**
@ -71,7 +72,7 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
} }
@Override @Override
public void establishIncomingBytestreamSession(final XMPPConnection connection) { public void establishIncomingBytestreamSession(final XMPPConnection connection, final JingleTransportCallback callback) {
final JingleSession session = getParent().getParent(); final JingleSession session = getParent().getParent();
final InBandBytestreamManager inBandBytestreamManager = InBandBytestreamManager.getByteStreamManager(connection); final InBandBytestreamManager inBandBytestreamManager = InBandBytestreamManager.getByteStreamManager(connection);
@ -81,20 +82,19 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
public void incomingBytestreamRequest(InBandBytestreamRequest request) { public void incomingBytestreamRequest(InBandBytestreamRequest request) {
if (request.getFrom().asFullJidIfPossible().equals(session.getPeer()) if (request.getFrom().asFullJidIfPossible().equals(session.getPeer())
&& request.getSessionID().equals(getSid())) { && request.getSessionID().equals(getSid())) {
BytestreamSession bytestreamSession;
inBandBytestreamManager.removeIncomingBytestreamListener(this); inBandBytestreamManager.removeIncomingBytestreamListener(this);
BytestreamSession bytestreamSession;
try { try {
bytestreamSession = request.accept(); bytestreamSession = request.accept();
} catch (InterruptedException | SmackException e) { } catch (InterruptedException | SmackException e) {
getParent().onTransportFailed(e); callback.onTransportFailed(e);
return; return;
} }
JingleIBBTransport.this.bytestreamSession = bytestreamSession; JingleIBBTransport.this.bytestreamSession = bytestreamSession;
callback.onTransportReady(JingleIBBTransport.this.bytestreamSession);
getParent().onTransportReady();
} }
} }
}; };
@ -104,15 +104,15 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
} }
@Override @Override
public void establishOutgoingBytestreamSession(XMPPConnection connection) { public void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback) {
JingleSession session = getParent().getParent(); JingleSession session = getParent().getParent();
InBandBytestreamManager inBandBytestreamManager = InBandBytestreamManager.getByteStreamManager(connection); InBandBytestreamManager inBandBytestreamManager = InBandBytestreamManager.getByteStreamManager(connection);
inBandBytestreamManager.setDefaultBlockSize(blockSize); inBandBytestreamManager.setDefaultBlockSize(blockSize);
try { try {
JingleIBBTransport.this.bytestreamSession = inBandBytestreamManager.establishSession(session.getPeer(), getSid()); JingleIBBTransport.this.bytestreamSession = inBandBytestreamManager.establishSession(session.getPeer(), getSid());
getParent().onTransportReady(); callback.onTransportReady(this.bytestreamSession);
} catch (SmackException.NoResponseException | XMPPException.XMPPErrorException | InterruptedException | SmackException.NotConnectedException e) { } catch (SmackException.NoResponseException | XMPPException.XMPPErrorException | InterruptedException | SmackException.NotConnectedException e) {
getParent().onTransportFailed(e); callback.onTransportFailed(e);
} }
} }

View file

@ -34,6 +34,7 @@ import org.jivesoftware.smackx.bytestreams.socks5.Socks5Proxy;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5Utils; import org.jivesoftware.smackx.bytestreams.socks5.Socks5Utils;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jivesoftware.smackx.jingle.JingleManager; import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement; import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement;
import org.jivesoftware.smackx.jingle.element.JingleElement; import org.jivesoftware.smackx.jingle.element.JingleElement;
import org.jivesoftware.smackx.jingle.exception.FailedTransportException; import org.jivesoftware.smackx.jingle.exception.FailedTransportException;
@ -67,6 +68,8 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
// PEERS candidate of OUR choice. // PEERS candidate of OUR choice.
private JingleS5BTransportCandidate selectedCandidate; private JingleS5BTransportCandidate selectedCandidate;
private JingleTransportCallback callback;
/** /**
* Create fresh JingleS5BTransport. * Create fresh JingleS5BTransport.
* @param initiator initiator. * @param initiator initiator.
@ -125,14 +128,16 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
} }
@Override @Override
public void establishIncomingBytestreamSession(XMPPConnection connection) public void establishIncomingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback)
throws SmackException.NotConnectedException, InterruptedException { throws SmackException.NotConnectedException, InterruptedException {
this.callback = callback;
establishBytestreamSession(connection); establishBytestreamSession(connection);
} }
@Override @Override
public void establishOutgoingBytestreamSession(XMPPConnection connection) public void establishOutgoingBytestreamSession(XMPPConnection connection, JingleTransportCallback callback)
throws SmackException.NotConnectedException, InterruptedException { throws SmackException.NotConnectedException, InterruptedException {
this.callback = callback;
establishBytestreamSession(connection); establishBytestreamSession(connection);
} }
@ -182,7 +187,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
if (getSelectedCandidate() == CANDIDATE_FAILURE && peers.getSelectedCandidate() == CANDIDATE_FAILURE) { if (getSelectedCandidate() == CANDIDATE_FAILURE && peers.getSelectedCandidate() == CANDIDATE_FAILURE) {
LOGGER.log(Level.INFO, "Failure."); LOGGER.log(Level.INFO, "Failure.");
getParent().onTransportFailed(new FailedTransportException(null)); callback.onTransportFailed(new FailedTransportException(null));
return; return;
} }
@ -215,7 +220,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
nominated = nominated.connect(MAX_TIMEOUT); nominated = nominated.connect(MAX_TIMEOUT);
} catch (InterruptedException | IOException | XMPPException | SmackException | TimeoutException e) { } catch (InterruptedException | IOException | XMPPException | SmackException | TimeoutException e) {
LOGGER.log(Level.INFO, "Could not connect to our candidate.", e); LOGGER.log(Level.INFO, "Could not connect to our candidate.", e);
getParent().onTransportFailed(new S5BTransportException.CandidateError(e)); callback.onTransportFailed(new S5BTransportException.CandidateError(e));
return; return;
} }
@ -233,7 +238,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
getParent().getParent().getJingleManager().getConnection().createStanzaCollectorAndSend(activate).nextResultOrThrow(); getParent().getParent().getJingleManager().getConnection().createStanzaCollectorAndSend(activate).nextResultOrThrow();
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) { } catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
LOGGER.log(Level.WARNING, "Could not activate proxy.", e); LOGGER.log(Level.WARNING, "Could not activate proxy.", e);
getParent().onTransportFailed(new S5BTransportException.ProxyError(e)); callback.onTransportFailed(new S5BTransportException.ProxyError(e));
return; return;
} }
@ -245,14 +250,14 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
.nextResultOrThrow(); .nextResultOrThrow();
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) { } catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
LOGGER.log(Level.WARNING, "Could not send candidate-activated", e); LOGGER.log(Level.WARNING, "Could not send candidate-activated", e);
getParent().onTransportFailed(new S5BTransportException.ProxyError(e)); callback.onTransportFailed(new S5BTransportException.ProxyError(e));
return; return;
} }
} }
LOGGER.log(Level.INFO, "Start transmission."); LOGGER.log(Level.INFO, "Start transmission.");
this.bytestreamSession = new Socks5BytestreamSession(nominated.getSocket(), !isProxy); this.bytestreamSession = new Socks5BytestreamSession(nominated.getSocket(), !isProxy);
getParent().onTransportReady(); callback.onTransportReady(this.bytestreamSession);
} }
//Our choice //Our choice
@ -262,7 +267,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
if (!isProxy) { if (!isProxy) {
LOGGER.log(Level.INFO, "Direct connection."); LOGGER.log(Level.INFO, "Direct connection.");
this.bytestreamSession = new Socks5BytestreamSession(nominated.getSocket(), true); this.bytestreamSession = new Socks5BytestreamSession(nominated.getSocket(), true);
getParent().onTransportReady(); callback.onTransportReady(this.bytestreamSession);
} else { } else {
LOGGER.log(Level.INFO, "Our choice was their external proxy. wait for candidate-activate."); LOGGER.log(Level.INFO, "Our choice was their external proxy. wait for candidate-activate.");
} }
@ -328,7 +333,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
private void handleCandidateActivate(JingleS5BTransportInfoElement info) { private void handleCandidateActivate(JingleS5BTransportInfoElement info) {
this.bytestreamSession = new Socks5BytestreamSession(getSelectedCandidate().getSocket(), this.bytestreamSession = new Socks5BytestreamSession(getSelectedCandidate().getSocket(),
getSelectedCandidate().getStreamHost().getJID().asBareJid().equals(getParent().getParent().getPeer().asBareJid())); getSelectedCandidate().getStreamHost().getJID().asBareJid().equals(getParent().getParent().getPeer().asBareJid()));
getParent().onTransportReady(); callback.onTransportReady(this.bytestreamSession);
} }
private void handleCandidateError(JingleS5BTransportInfoElement info) { private void handleCandidateError(JingleS5BTransportInfoElement info) {
@ -337,7 +342,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
} }
private void handleProxyError(JingleS5BTransportInfoElement info) { private void handleProxyError(JingleS5BTransportInfoElement info) {
//TODO callback.onTransportFailed(new S5BTransportException.ProxyError(null));
} }
public void setSelectedCandidate(JingleS5BTransportCandidate candidate) { public void setSelectedCandidate(JingleS5BTransportCandidate candidate) {

View file

@ -0,0 +1,77 @@
package org.jivesoftware.smackx.jingle;
import static junit.framework.TestCase.fail;
import java.io.IOException;
import java.util.Random;
import java.util.logging.Level;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.transport.jingle_ibb.JingleIBBTransport;
import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest;
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint;
import org.junit.Assert;
/**
* Created by vanitas on 27.07.17.
*/
public class JingleIBBTest extends AbstractSmackIntegrationTest {
public JingleIBBTest(SmackIntegrationTestEnvironment environment) {
super(environment);
}
@SmackIntegrationTest
public void testIBBTransport() throws Exception {
JingleIBBTransport sender = new JingleIBBTransport();
JingleIBBTransport receiver = new JingleIBBTransport();
final SimpleResultSyncPoint recvPoint = new SimpleResultSyncPoint();
final byte[] data = new byte[512];
new Random().nextBytes(data);
final byte[] recv = new byte[512];
receiver.establishIncomingBytestreamSession(conOne, new JingleTransportCallback() {
@Override
public void onTransportReady(BytestreamSession bytestreamSession) {
try {
bytestreamSession.getInputStream().read(recv);
bytestreamSession.getInputStream().close();
recvPoint.signal();
} catch (IOException e) {
fail(e.toString());
}
}
@Override
public void onTransportFailed(Exception e) {
LOGGER.log(Level.SEVERE, e.toString());
recvPoint.signal();
}
});
sender.establishOutgoingBytestreamSession(conTwo, new JingleTransportCallback() {
@Override
public void onTransportReady(BytestreamSession bytestreamSession) {
try {
bytestreamSession.getOutputStream().write(data);
} catch (IOException e) {
fail(e.toString());
}
}
@Override
public void onTransportFailed(Exception e) {
}
});
recvPoint.wait(10 * 1000);
Assert.assertArrayEquals(data, recv);
}
}