Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Stieber2014-06-12 10:53:25 +0000
committerUwe Stieber2014-06-12 10:53:25 +0000
commit4458fad0c8a9fec8634f425505ed9bf1deef8402 (patch)
treeef09ec55626d55bc247eab4a38046a620c01c7b1
parentace29dbdea46bb91d8bef2f3dd145110a788f18b (diff)
downloadorg.eclipse.tcf-4458fad0c8a9fec8634f425505ed9bf1deef8402.tar.gz
org.eclipse.tcf-4458fad0c8a9fec8634f425505ed9bf1deef8402.tar.xz
org.eclipse.tcf-4458fad0c8a9fec8634f425505ed9bf1deef8402.zip
Target Explorer: Add support to connect to a target via proxies without value-add's
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java180
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.java1
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.properties1
3 files changed, 180 insertions, 2 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java
index ffa0b25dc..1fc69e1e5 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java
@@ -137,8 +137,16 @@ public final class ChannelManager extends PlatformObject implements IChannelMana
// There are value-add's -> chain them now
internalChainValueAdds(valueAdds, peer, flags, finInnerDone);
} else {
- // No value-add's -> open a channel to the target peer directly
- internalOpenChannel(peer, flags, finInnerDone);
+ // Determine the proxy configuration
+ String proxyConfiguration = peer.getAttributes().get(IPeerProperties.PROP_PROXIES);
+ IPeer[] proxies = proxyConfiguration != null ? PeerDataHelper.decodePeerList(proxyConfiguration) : null;
+ if (proxies != null && proxies.length > 0) {
+ // There are proxies -> chain them now
+ internalChainProxies(proxies, peer, flags, finInnerDone);
+ } else {
+ // No value-add's and no proxies -> open a channel to the target peer directly
+ internalOpenChannel(peer, flags, finInnerDone);
+ }
}
} else {
// Shutdown the value-add's launched
@@ -1174,6 +1182,174 @@ public final class ChannelManager extends PlatformObject implements IChannelMana
}
}
+ /**
+ * Chain the proxies until the original target peer is reached.
+ *
+ * @param proxies The list of proxies to chain. Must not be <code>null</code>.
+ * @param peer The original target peer. Must not be <code>null</code>.
+ * @param flags Map containing the flags to parameterize the channel opening, or <code>null</code>.
+ * @param done The client callback. Must not be <code>null</code>.
+ */
+ /* default */ void internalChainProxies(final IPeer[] proxies, final IPeer peer, final Map<String, Boolean> flags, final DoneOpenChannel done) {
+ Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
+ Assert.isNotNull(proxies);
+ Assert.isTrue(proxies.length > 0);
+ Assert.isNotNull(peer);
+ Assert.isNotNull(done);
+
+ // Get the peer id
+ final String id = peer.getID();
+
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) {
+ CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_proxies_startChaining, id),
+ 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this);
+ }
+
+ // Extract the flags of interest form the given flags map
+ boolean forceNew = flags != null && flags.containsKey(IChannelManager.FLAG_FORCE_NEW) ? flags.get(IChannelManager.FLAG_FORCE_NEW).booleanValue() : false;
+ boolean noValueAdd = flags != null && flags.containsKey(IChannelManager.FLAG_NO_VALUE_ADD) ? flags.get(IChannelManager.FLAG_NO_VALUE_ADD).booleanValue() : false;
+ boolean noPathMap = flags != null && flags.containsKey(IChannelManager.FLAG_NO_PATH_MAP) ? flags.get(IChannelManager.FLAG_NO_PATH_MAP).booleanValue() : false;
+ // If noValueAdd == true or noPathMap == true -> forceNew has to be true as well
+ if (noValueAdd || noPathMap) forceNew = true;
+
+ final boolean finForceNew = forceNew;
+
+ // Check if there is already a channel opened to this peer
+ IChannel channel = !forceNew ? channels.get(id) : null;
+ if (channel != null && (channel.getState() == IChannel.STATE_OPEN || channel.getState() == IChannel.STATE_OPENING)) {
+ // Increase the reference count
+ AtomicInteger counter = refCounters.get(id);
+ if (counter == null) {
+ counter = new AtomicInteger(0);
+ refCounters.put(id, counter);
+ }
+ counter.incrementAndGet();
+
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) {
+ CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_reuse_message, id, counter.toString()),
+ 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this);
+ }
+ // Got an existing channel -> drop out immediately if the channel is
+ // already fully opened. Otherwise wait for the channel to be fully open.
+ if (channel.getState() == IChannel.STATE_OPENING) {
+ final IChannel finChannel = channel;
+ channel.addChannelListener(new IChannel.IChannelListener() {
+ @Override
+ public void onChannelOpened() {
+ done.doneOpenChannel(null, finChannel);
+ }
+ @Override
+ public void onChannelClosed(Throwable error) {
+ done.doneOpenChannel(error != null ? error : new OperationCanceledException(), finChannel);
+ }
+ @Override
+ public void congestionLevel(int level) {
+ }
+ });
+ }
+ else {
+ done.doneOpenChannel(null, channel);
+ }
+ return;
+ } else if (channel != null) {
+ // Channel is not in open state -> drop the instance
+ channels.remove(id);
+ refCounters.remove(id);
+ }
+
+ // No existing channel -> open a new one
+
+ // Get the first proxy. This is the one we have to open the channel too.
+ IPeer firstProxy = proxies[0];
+ Assert.isNotNull(firstProxy);
+
+ // Remove the first proxy from the array and build up a new array describing
+ // the remaining proxy chain
+ final IPeer[] remainingProxies = new IPeer[proxies.length - 1];
+ if (remainingProxies.length > 0) System.arraycopy(proxies, 1, remainingProxies, 0, remainingProxies.length);
+
+ // Open a channel to the first proxy
+ channel = null;
+ try {
+ channel = firstProxy.openChannel();
+ if (channel != null) {
+ if (!forceNew) channels.put(id, channel);
+ if (!forceNew) refCounters.put(id, new AtomicInteger(1));
+ if (forceNew) forcedChannels.add(channel);
+
+ // Create and attach the channel listener to catch open/closed events
+ final IChannel finChannel = channel;
+ final IChannel.IChannelListener finChannelListener = new IChannel.IChannelListener() {
+ @Override
+ public void onChannelOpened() {
+ // Remove ourself as channel listener
+ finChannel.removeChannelListener(this);
+
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) {
+ CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_success_message, id),
+ 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, ChannelManager.this);
+ }
+
+ // Channel opened to the first proxy. Process the proxy chain and
+ // redirect the channel through the proxies until the original target
+ // is reached
+ final DoneChainProxies chainProxiesDone = new DoneChainProxies() {
+ @Override
+ public void doneChainProxies(final Throwable error, final IChannel channel) {
+ // Invoke the outer callback
+ done.doneOpenChannel(error, channel);
+ }
+ };
+
+ // Continue the redirect chain by chaining the proxies and connecting to the target
+ doChainProxies(id, peer.getAttributes(), remainingProxies, finForceNew, 0, finChannel, chainProxiesDone);
+ }
+
+ @Override
+ public void onChannelClosed(Throwable error) {
+ // Remove ourself as channel listener
+ finChannel.removeChannelListener(this);
+
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) {
+ CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_failed_message, id, error),
+ 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, ChannelManager.this);
+ }
+
+ // Clean the reference counter and the channel map
+ if (!finForceNew) channels.remove(id);
+ if (!finForceNew) refCounters.remove(id);
+ if (finForceNew) forcedChannels.remove(finChannel);
+
+ // Channel open failed -> This will break everything
+ done.doneOpenChannel(error, finChannel);
+ }
+
+ @Override
+ public void congestionLevel(int level) {
+ }
+ };
+ channel.addChannelListener(finChannelListener);
+ } else {
+ // Channel is null? Something went terrible wrong.
+ done.doneOpenChannel(new Exception("Unexpected null return value from IPeer#openChannel()!"), null); //$NON-NLS-1$
+
+ }
+ } catch (Throwable e) {
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) {
+ CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_failed_message, id, e),
+ 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this);
+ }
+
+ // Channel opening failed
+ done.doneOpenChannel(e, channel);
+ }
+
+
+
+
+
+ }
+
/* default */ void doChainProxies(final String id, final Map<String, String> attrs, final IPeer[] proxies, final boolean forceNew, final int numberOfValueAdds, final IChannel channel, final DoneChainProxies done) {
Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
Assert.isNotNull(id);
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.java
index 3e738ea6d..d1a99c3b9 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.java
@@ -83,6 +83,7 @@ public class Messages extends NLS {
public static String ChannelManager_openChannel_valueAdd_isAlive;
public static String ChannelManager_openChannel_valueAdd_launch;
public static String ChannelManager_openChannel_valueAdd_startChaining;
+ public static String ChannelManager_openChannel_proxies_startChaining;
public static String ChannelManager_openChannel_redirect_succeeded;
public static String ChannelManager_openChannel_redirect_failed;
public static String ChannelManager_openChannel_redirect_invalidChannelState;
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.properties
index 11fcc50a4..4386489db 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/nls/Messages.properties
@@ -24,6 +24,7 @@ ChannelManager_openChannel_valueAdd_numApplicable={0} applicable value-add contr
ChannelManager_openChannel_valueAdd_isAlive=Value-add #{0} ({1}): isAlive = {2}. Target id = {3}
ChannelManager_openChannel_valueAdd_launch=Value-add #{0} ({1}): launch {2} (error = ''{3}''). Target id = {4}
ChannelManager_openChannel_valueAdd_startChaining=Start chaining of value-add's. Target id = {0}
+ChannelManager_openChannel_proxies_startChaining=Start chaining of proxies. Target id = {0}
ChannelManager_openChannel_redirect_succeeded=Successfully redirected channel from {0} to {1}. Redirect Level = {2}
ChannelManager_openChannel_redirect_failed=Failed to redirect channel from {0} to {1}.
ChannelManager_openChannel_redirect_invalidChannelState=Channel not in open state. Cannot redirect channel to {1}.

Back to the top