Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2010-07-12 17:15:27 -0400
committereutarass2010-07-12 17:15:27 -0400
commit3f0dda210a02e7f905561566a7c774a83408d762 (patch)
tree63f3da39494db8d1ff861b2c5f99bb712c72337e /plugins/org.eclipse.tm.tcf.core
parentd72141d6ce4d9b4b53a1238f10d7143b6c721e40 (diff)
downloadorg.eclipse.tcf-3f0dda210a02e7f905561566a7c774a83408d762.tar.gz
org.eclipse.tcf-3f0dda210a02e7f905561566a7c774a83408d762.tar.xz
org.eclipse.tcf-3f0dda210a02e7f905561566a7c774a83408d762.zip
Locator.redirect command changed to allow command argument to be either peer ID or complete set of peer attributes.
This allow a client to redirect a channel to a peer that is not known by remote Locator.
Diffstat (limited to 'plugins/org.eclipse.tm.tcf.core')
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java4
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java13
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractChannel.java94
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IChannel.java7
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILocator.java6
5 files changed, 94 insertions, 30 deletions
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java
index 249589571..21ec0fb62 100644
--- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java
+++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/local/LocatorService.java
@@ -1070,6 +1070,10 @@ public class LocatorService implements ILocator {
throw new Error("Channel redirect cannot be done on local peer");
}
+ public IToken redirect(Map<String,String> peer, DoneRedirect done) {
+ throw new Error("Channel redirect cannot be done on local peer");
+ }
+
public IToken sync(DoneSync done) {
throw new Error("Channel sync cannot be done on local peer");
}
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java
index 3415fa321..94ec1ff91 100644
--- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java
+++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/LocatorProxy.java
@@ -190,6 +190,19 @@ public class LocatorProxy implements ILocator {
}.token;
}
+ public IToken redirect(Map<String,String> peer, final DoneRedirect done) {
+ return new Command(channel, this, "redirect", new Object[]{ peer }) {
+ @Override
+ public void done(Exception error, Object[] args) {
+ if (error == null) {
+ assert args.length == 1;
+ error = toError(args[0]);
+ }
+ done.doneRedirect(token, error);
+ }
+ }.token;
+ }
+
public IToken sync(final DoneSync done) {
return new Command(channel, this, "sync", null) {
@Override
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractChannel.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractChannel.java
index dc6ac4eac..14cb5af62 100644
--- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractChannel.java
+++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/core/AbstractChannel.java
@@ -118,7 +118,7 @@ public abstract class AbstractChannel implements IChannel {
private static IChannelListener[] listeners_array = new IChannelListener[4];
- private final LinkedList<String> redirect_queue = new LinkedList<String>();
+ private final LinkedList<Map<String,String>> redirect_queue = new LinkedList<Map<String,String>>();
private final Map<Class<?>,IService> local_service_by_class = new HashMap<Class<?>,IService>();
private final Map<Class<?>,IService> remote_service_by_class = new HashMap<Class<?>,IService>();
private final Map<String,IService> local_service_by_name = new HashMap<String,IService>();
@@ -398,10 +398,20 @@ public abstract class AbstractChannel implements IChannel {
* Redirect this channel to given peer using this channel remote peer locator service as a proxy.
* @param peer_id - peer that will become new remote communication endpoint of this channel
*/
- public void redirect(final String peer_id) {
+ public void redirect(String peer_id) {
+ Map<String,String> map = new HashMap<String,String>();
+ map.put(IPeer.ATTR_ID, peer_id);
+ redirect(map);
+ }
+
+ /**
+ * Redirect this channel to given peer using this channel remote peer locator service as a proxy.
+ * @param peer_attrs - peer that will become new remote communication endpoint of this channel
+ */
+ public void redirect(final Map<String,String> peer_attrs) {
assert Protocol.isDispatchThread();
if (state == STATE_OPENNING) {
- redirect_queue.add(peer_id);
+ redirect_queue.add(peer_attrs);
}
else {
assert state == STATE_OPEN;
@@ -410,43 +420,67 @@ public abstract class AbstractChannel implements IChannel {
final ILocator l = (ILocator)remote_service_by_class.get(ILocator.class);
if (l == null) throw new IOException("Cannot redirect channel: peer " +
remote_peer.getID() + " has no locator service");
- final IPeer peer = l.getPeers().get(peer_id);
- if (peer == null) {
- // Peer not found, must wait for a while until peer is discovered or time out
- final boolean[] found = new boolean[1];
- Protocol.invokeLater(ILocator.DATA_RETENTION_PERIOD / 3, new Runnable() {
- public void run() {
- if (found[0]) return;
- terminate(new Exception("Peer " + peer_id + " not found"));
- }
- });
- l.addListener(new ILocator.LocatorListener() {
- public void peerAdded(IPeer peer) {
- if (peer.getID().equals(peer_id)) {
- found[0] = true;
- state = STATE_OPEN;
- l.removeListener(this);
- redirect(peer_id);
+ final String peer_id = peer_attrs.get(IPeer.ATTR_ID);
+ if (peer_id != null && peer_attrs.size() == 1) {
+ final IPeer peer = l.getPeers().get(peer_id);
+ if (peer == null) {
+ // Peer not found, must wait for a while until peer is discovered or time out
+ final boolean[] found = new boolean[1];
+ Protocol.invokeLater(ILocator.DATA_RETENTION_PERIOD / 3, new Runnable() {
+ public void run() {
+ if (found[0]) return;
+ terminate(new Exception("Peer " + peer_id + " not found"));
+ }
+ });
+ l.addListener(new ILocator.LocatorListener() {
+ public void peerAdded(IPeer peer) {
+ if (peer.getID().equals(peer_id)) {
+ found[0] = true;
+ state = STATE_OPEN;
+ l.removeListener(this);
+ redirect(peer_id);
+ }
+ }
+ public void peerChanged(IPeer peer) {
}
- }
- public void peerChanged(IPeer peer) {
- }
- public void peerHeartBeat(String id) {
- }
+ public void peerHeartBeat(String id) {
+ }
- public void peerRemoved(String id) {
- }
- });
+ public void peerRemoved(String id) {
+ }
+ });
+ }
+ else {
+ redirect_command = l.redirect(peer_id, new ILocator.DoneRedirect() {
+ public void doneRedirect(IToken token, Exception x) {
+ assert redirect_command == token;
+ redirect_command = null;
+ if (state != STATE_OPENNING) return;
+ if (x != null) terminate(x);
+ remote_peer = peer;
+ remote_service_by_class.clear();
+ remote_service_by_name.clear();
+ event_listeners.clear();
+ }
+ });
+ }
}
else {
- redirect_command = l.redirect(peer_id, new ILocator.DoneRedirect() {
+ redirect_command = l.redirect(peer_attrs, new ILocator.DoneRedirect() {
public void doneRedirect(IToken token, Exception x) {
assert redirect_command == token;
redirect_command = null;
if (state != STATE_OPENNING) return;
if (x != null) terminate(x);
- remote_peer = peer;
+ final IPeer parent = remote_peer;
+ remote_peer = new AbstractPeer(peer_attrs) {
+ public IChannel openChannel() {
+ IChannel c = parent.openChannel();
+ c.redirect(peer_attrs);
+ return c;
+ }
+ };
remote_service_by_class.clear();
remote_service_by_name.clear();
event_listeners.clear();
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IChannel.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IChannel.java
index aabca468e..21ff2fa22 100644
--- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IChannel.java
+++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/IChannel.java
@@ -11,6 +11,7 @@
package org.eclipse.tm.tcf.protocol;
import java.util.Collection;
+import java.util.Map;
/**
* IChannel represents communication link connecting two end points (peers).
@@ -296,4 +297,10 @@ public interface IChannel {
* @param peer_id - peer that will become new remote communication endpoint of this channel
*/
void redirect(String peer_id);
+
+ /**
+ * Redirect this channel to given peer using this channel remote peer locator service as a proxy.
+ * @param peer_attrs - peer that will become new remote communication endpoint of this channel
+ */
+ void redirect(Map<String,String> peer_attrs);
}
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILocator.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILocator.java
index 8940a6f18..ddb88190e 100644
--- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILocator.java
+++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ILocator.java
@@ -69,6 +69,12 @@ public interface ILocator extends IService {
*/
IToken redirect(String peer_id, DoneRedirect done);
+ /**
+ * Redirect this service channel to given peer using this service as a proxy.
+ * @param peer - Peer attributes.
+ */
+ IToken redirect(Map<String,String> peer, DoneRedirect done);
+
interface DoneRedirect {
void doneRedirect(IToken token, Exception error);
}

Back to the top