implemented agent tunnel management GUI
authorVictor Kirhenshtein <victor@netxms.org>
Thu, 11 May 2017 22:26:18 +0000 (01:26 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Thu, 11 May 2017 22:26:18 +0000 (01:26 +0300)
25 files changed:
ChangeLog
include/nms_cscp.h
src/java/client/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/client/netxms-client/src/main/java/org/netxms/client/AgentTunnel.java
src/java/client/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/netxms-eclipse/AgentManager/OSGI-INF/l10n/bundle.properties
src/java/netxms-eclipse/AgentManager/icons/tunnel_manager.png [new file with mode: 0644]
src/java/netxms-eclipse/AgentManager/plugin.xml
src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenPackageManager.java
src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenTunnelManager.java [new file with mode: 0644]
src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/PackageManager.java
src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/TunnelManager.java [new file with mode: 0644]
src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/helpers/TunnelListLabelProvider.java [new file with mode: 0644]
src/libnetxms/nxcp.cpp
src/server/core/session.cpp
src/server/core/tunnel.cpp
src/server/include/nms_core.h
webui/webapp/AgentManager/OSGI-INF/l10n/bundle.properties
webui/webapp/AgentManager/icons/tunnel_manager.png [new file with mode: 0644]
webui/webapp/AgentManager/plugin.xml
webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenPackageManager.java
webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenTunnelManager.java [new file with mode: 0644]
webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/PackageManager.java
webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/TunnelManager.java [new file with mode: 0644]
webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/helpers/TunnelListLabelProvider.java [new file with mode: 0644]

index ccbad6e..344e96c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,7 @@
        - Node's zone name shown in alarm browser and object overview when zoning is enabled
        - Sorting option in table based charts on dashboards (to implement "Top N" style charts)
        - Full text object search
+       - Agent tunnel manager view
 - Fixed issues: NX-386, NX-1127, NX-1128, NX-1210, NX-1211, NX-1222, NX-1231, NX-1239, NX-1240, NX-1242 
 
 
index 49b4b8d..948acdc 100644 (file)
@@ -450,7 +450,7 @@ typedef struct
 #define CMD_GET_PERSISTENT_STORAGE        0x00D3
 #define CMD_DELETE_PSTORAGE_VALUE         0x00D4
 #define CMD_SET_PSTORAGE_VALUE            0x00D5
-#define CMD_GET_UNBOUND_AGENT_TUNNELS     0x00D6
+#define CMD_GET_AGENT_TUNNELS             0x00D6
 #define CMD_BIND_AGENT_TUNNEL             0x00D7
 #define CMD_REQUEST_CERTIFICATE           0x00D8
 #define CMD_NEW_CERTIFICATE               0x00D9
index b88ea2d..b1f920f 100644 (file)
@@ -237,7 +237,7 @@ public class NXCPCodes
        public static final int CMD_GET_PERSISTENT_STORAGE = 0x00D3;
        public static final int CMD_DELETE_PSTORAGE_VALUE = 0x00D4;
        public static final int CMD_SET_PSTORAGE_VALUE = 0x00D5;
-       public static final int CMD_GET_UNBOUND_AGENT_TUNNELS = 0x00D6;
+       public static final int CMD_GET_AGENT_TUNNELS = 0x00D6;
        public static final int CMD_BIND_AGENT_TUNNEL = 0x00D7;
        public static final int CMD_REQUEST_CERTIFICATE = 0x00D8;
        public static final int CMD_NEW_CERTIFICATE = 0x00D9;
index 16a8ea8..00b9bb5 100644 (file)
@@ -55,6 +55,16 @@ public class AgentTunnel
       agentVersion = msg.getFieldAsString(baseId + 7);
       activeChannelCount = msg.getFieldAsInt32(baseId + 8);
    }
+   
+   /**
+    * Check if tunnel is bound
+    * 
+    * @return true if tunnel is bound
+    */
+   public boolean isBound()
+   {
+      return nodeId != 0;
+   }
 
    /**
     * @return the id
index 97b1ec3..615a2ee 100644 (file)
@@ -9562,15 +9562,15 @@ public class NXCSession
    }
    
    /**
-    * Get list of unbound agent tunnels
+    * Get list of agent tunnels
     * 
-    * @return list of unbound agent tunnels
+    * @return list of agent tunnels
     * @throws IOException if socket I/O error occurs
     * @throws NXCException if NetXMS server returns an error or operation was timed out
     */
-   public List<AgentTunnel> getUnboundAgentTunnels() throws IOException, NXCException
+   public List<AgentTunnel> getAgentTunnels() throws IOException, NXCException
    {
-      final NXCPMessage msg = newMessage(NXCPCodes.CMD_GET_UNBOUND_AGENT_TUNNELS);
+      final NXCPMessage msg = newMessage(NXCPCodes.CMD_GET_AGENT_TUNNELS);
       sendMessage(msg);
       NXCPMessage response = waitForRCC(msg.getMessageId());
       int count = response.getFieldAsInt32(NXCPCodes.VID_NUM_ELEMENTS);
index 6f0c49a..a14296a 100644 (file)
@@ -1,7 +1,9 @@
 action.openAgentConfigManager=Agent Configurations
 action.openPackageManager=Package Manager
+action.openTunnelManager=Agent Tunnel Manager
 actionDescription.openAgentConfigManager=Open agent configuration manager
 actionDescription.openPackageManager=Open package manager
+actionDescription.openTunnelManager=Open agent tunnel manager
 actionSet.AgentManagement=Agent Management
 menu.EditConfig=Edit agent's configuration file
 menu.TakeScreenshot=Take screenshot
@@ -10,3 +12,4 @@ view.AgentConfigManager=Agent Configuration Manager
 view.PackageDeploymentMonitor=Package Deployment Monitor
 view.PackageManager=Package Manager
 view.Screenshot=Screenshot
+view.TunnelManager=Agent Tunnel Manager
diff --git a/src/java/netxms-eclipse/AgentManager/icons/tunnel_manager.png b/src/java/netxms-eclipse/AgentManager/icons/tunnel_manager.png
new file mode 100644 (file)
index 0000000..a44fdd3
Binary files /dev/null and b/src/java/netxms-eclipse/AgentManager/icons/tunnel_manager.png differ
index 5528888..522b6e1 100644 (file)
             name="%view.Screenshot"
             restorable="false">
       </view>
+      <view
+            allowMultiple="false"
+            class="org.netxms.ui.eclipse.agentmanager.views.TunnelManager"
+            icon="icons/tunnel_manager.png"
+            id="org.netxms.ui.eclipse.agentmanager.views.TunnelManager"
+            name="Agent Tunnel Manager"
+            restorable="true">
+      </view>
    </extension>
    <extension
          point="org.eclipse.ui.popupMenus">
                toolbarPath="config/additions"
                tooltip="%actionDescription.openPackageManager">
          </action>
+         <action
+               class="org.netxms.ui.eclipse.agentmanager.actions.OpenTunnelManager"
+               definitionId="org.netxms.ui.eclipse.agentmanager.commands.open_tunnel_manager"
+               icon="icons/tunnel_manager.png"
+               id="org.netxms.ui.eclipse.agentmanager.actions.open_tunnel_manager"
+               label="%action.openTunnelManager"
+               menubarPath="config/additions"
+               style="push"
+               toolbarPath="config/additions"
+               tooltip="%actionDescription.openTunnelManager">
+         </action>
       </actionSet>
    </extension>
    <extension
             id="org.netxms.ui.eclipse.agentmanager.commands.copy_screenshot"
             name="Copy screenshot">
       </command>
+      <command
+            categoryId="org.netxms.ui.eclipse.console.category.views"
+            description="%actionDescription.openTunnelManager"
+            id="org.netxms.ui.eclipse.agentmanager.commands.open_tunnel_manager"
+            name="%action.openTunnelManager">
+      </command>
    </extension>
    <extension
          point="org.eclipse.ui.contexts">
index f393af3..57d2077 100644 (file)
  */
 package org.netxms.ui.eclipse.agentmanager.actions;
 
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-import org.eclipse.ui.PartInitException;
-import org.netxms.ui.eclipse.agentmanager.Messages;
+import org.netxms.ui.eclipse.actions.OpenView;
 import org.netxms.ui.eclipse.agentmanager.views.PackageManager;
-import org.netxms.ui.eclipse.tools.MessageDialogHelper;
 
-public class OpenPackageManager implements IWorkbenchWindowActionDelegate
+/**
+ * Open package manager view
+ */
+public class OpenPackageManager extends OpenView
 {
-       private IWorkbenchWindow window;
-       
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
-        */
-       @Override
-       public void dispose()
-       {
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
-        */
-       @Override
-       public void init(IWorkbenchWindow window)
-       {
-               this.window = window;
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
-        */
-       @Override
-       public void run(IAction action)
-       {
-               if(window != null)
-               {       
-                       try 
-                       {
-                               window.getActivePage().showView(PackageManager.ID);
-                       } 
-                       catch (PartInitException e) 
-                       {
-                               MessageDialogHelper.openError(window.getShell(), Messages.get().OpenPackageManager_Error, Messages.get().OpenPackageManager_ErrorOpenView + e.getMessage());
-                       }
-               }
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
-        */
-       @Override
-       public void selectionChanged(IAction action, ISelection selection)
-       {
-       }
+   /* (non-Javadoc)
+    * @see org.netxms.ui.eclipse.actions.OpenView#getViewId()
+    */
+   @Override
+   protected String getViewId()
+   {
+      return PackageManager.ID;
+   }
 }
diff --git a/src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenTunnelManager.java b/src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenTunnelManager.java
new file mode 100644 (file)
index 0000000..93e3870
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.agentmanager.actions;
+
+import org.netxms.ui.eclipse.actions.OpenView;
+import org.netxms.ui.eclipse.agentmanager.views.TunnelManager;
+
+/**
+ * Open tunnel manager view
+ */
+public class OpenTunnelManager extends OpenView
+{
+   /* (non-Javadoc)
+    * @see org.netxms.ui.eclipse.actions.OpenView#getViewId()
+    */
+   @Override
+   protected String getViewId()
+   {
+      return TunnelManager.ID;
+   }
+}
index 2350780..8212166 100644 (file)
@@ -160,7 +160,7 @@ public class PackageManager extends ViewPart
         */
        private void createActions()
        {
-               actionRefresh = new RefreshAction() {
+               actionRefresh = new RefreshAction(this) {
                        @Override
                        public void run()
                        {
@@ -266,7 +266,7 @@ public class PackageManager extends ViewPart
         */
        private void refresh()
        {
-               final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
+               final NXCSession session = ConsoleSharedData.getSession();
                new ConsoleJob(Messages.get().PackageManager_LoadPkgList, this, Activator.PLUGIN_ID, null) {
                        @Override
                        protected void runInternal(IProgressMonitor monitor) throws Exception
diff --git a/src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/TunnelManager.java b/src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/TunnelManager.java
new file mode 100644 (file)
index 0000000..a370df4
--- /dev/null
@@ -0,0 +1,316 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.agentmanager.views;
+
+import java.util.List;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.part.ViewPart;
+import org.netxms.client.AgentTunnel;
+import org.netxms.client.NXCSession;
+import org.netxms.ui.eclipse.actions.RefreshAction;
+import org.netxms.ui.eclipse.agentmanager.Activator;
+import org.netxms.ui.eclipse.agentmanager.views.helpers.TunnelListLabelProvider;
+import org.netxms.ui.eclipse.jobs.ConsoleJob;
+import org.netxms.ui.eclipse.objectbrowser.dialogs.ObjectSelectionDialog;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+import org.netxms.ui.eclipse.tools.MessageDialogHelper;
+import org.netxms.ui.eclipse.widgets.SortableTableViewer;
+
+/**
+ * Tunnel manager view
+ */
+public class TunnelManager extends ViewPart
+{
+   public static final String ID = "org.netxms.ui.eclipse.agentmanager.views.TunnelManager";
+   
+   public static final int COL_ID = 0;
+   public static final int COL_STATE = 1;
+   public static final int COL_NODE = 2;
+   public static final int COL_IP_ADDRESS = 3;
+   public static final int COL_CHANNELS = 4;
+   public static final int COL_SYSNAME = 5;
+   public static final int COL_PLATFORM = 6;
+   public static final int COL_SYSINFO = 7;
+   public static final int COL_AGENT_VERSION = 8;
+   
+   private SortableTableViewer viewer;
+   private Action actionRefresh;
+   private Action actionBind;
+   private Action actionUnbind;
+   
+   /* (non-Javadoc)
+    * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+    */
+   @Override
+   public void createPartControl(Composite parent)
+   {
+      final String[] names = { "ID", "State", "Node", "IP address", "Channels", "System name", "Platform", "System information", "Agent version" };
+      final int[] widths = { 80, 80, 140, 150, 80, 150, 150, 300, 150 };
+      viewer = new SortableTableViewer(parent, names, widths, 0, SWT.UP, SWT.FULL_SELECTION);
+      viewer.setContentProvider(new ArrayContentProvider());
+      viewer.setLabelProvider(new TunnelListLabelProvider());
+      
+      createActions();
+      contributeToActionBars();
+      createPopupMenu();
+      
+      refresh();
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
+    */
+   @Override
+   public void setFocus()
+   {
+      viewer.getTable().setFocus();
+   }
+
+   /**
+    * Create actions
+    */
+   private void createActions()
+   {
+      actionRefresh = new RefreshAction(this) {
+         @Override
+         public void run()
+         {
+            refresh();
+         }
+      };
+      
+      actionBind = new Action("&Bind to...") {
+         @Override
+         public void run()
+         {
+            bindTunnel();
+         }
+      };
+      
+      actionUnbind = new Action("&Unbind") {
+         @Override
+         public void run()
+         {
+            unbindTunnel();
+         }
+      };
+   }
+
+   /**
+    * Contribute actions to action bars
+    */
+   private void contributeToActionBars()
+   {
+      IActionBars bars = getViewSite().getActionBars();
+      fillLocalPullDown(bars.getMenuManager());
+      fillLocalToolBar(bars.getToolBarManager());
+   }
+
+   /**
+    * Fill local pulldown menu
+    * @param manager menu manager
+    */
+   private void fillLocalPullDown(IMenuManager manager)
+   {
+      manager.add(actionRefresh);
+   }
+
+   /**
+    * Fill local toolbar
+    * @param manager menu manager
+    */
+   private void fillLocalToolBar(IToolBarManager manager)
+   {
+      manager.add(actionRefresh);
+   }
+
+   /**
+    * Create pop-up menu
+    */
+   private void createPopupMenu()
+   {
+      // Create menu manager.
+      MenuManager menuMgr = new MenuManager();
+      menuMgr.setRemoveAllWhenShown(true);
+      menuMgr.addMenuListener(new IMenuListener() {
+         public void menuAboutToShow(IMenuManager mgr)
+         {
+            fillContextMenu(mgr);
+         }
+      });
+
+      // Create menu.
+      Menu menu = menuMgr.createContextMenu(viewer.getControl());
+      viewer.getControl().setMenu(menu);
+
+      // Register menu for extension.
+      getSite().registerContextMenu(menuMgr, viewer);
+   }
+   
+   /**
+    * Fill context menu
+    * @param manager Menu manager
+    */
+   protected void fillContextMenu(IMenuManager manager)
+   {
+      IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+      if ((selection.size() == 1) && !((AgentTunnel)selection.getFirstElement()).isBound())
+      {
+         manager.add(actionBind);
+      }
+      else
+      {
+         for(Object o : selection.toList())
+         {
+            if (((AgentTunnel)o).isBound())
+            {
+               manager.add(actionUnbind);
+               break;
+            }
+         }
+      }
+   }
+   
+   /**
+    * Refresh view
+    */
+   private void refresh()
+   {
+      final NXCSession session = ConsoleSharedData.getSession();
+      new ConsoleJob("Get list of active agent tunnels", this, Activator.PLUGIN_ID, null) {
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            final List<AgentTunnel> tunnels = session.getAgentTunnels();
+            runInUIThread(new Runnable() {
+               @Override
+               public void run()
+               {
+                  viewer.setInput(tunnels);
+               }
+            });
+         }
+         
+         @Override
+         protected String getErrorMessage()
+         {
+            return "Cannot get list of active agent tunnels";
+         }
+      }.start();
+   }
+   
+   /**
+    * Bind tunnel to node
+    */
+   private void bindTunnel()
+   {
+      IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+      if (selection.size() != 1)
+         return;
+      
+      final AgentTunnel tunnel = (AgentTunnel)selection.getFirstElement();
+      if (tunnel.isBound())
+         return;
+      
+      ObjectSelectionDialog dlg = new ObjectSelectionDialog(getSite().getShell(), null, ObjectSelectionDialog.createNodeSelectionFilter(false));
+      if (dlg.open() != Window.OK)
+         return;      
+      final long nodeId = dlg.getSelectedObjects().get(0).getObjectId();
+      
+      final NXCSession session = ConsoleSharedData.getSession();
+      new ConsoleJob("Bind tunnels", this, Activator.PLUGIN_ID, null) {
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            session.bindAgentTunnel(tunnel.getId(), nodeId);
+
+            final List<AgentTunnel> tunnels = session.getAgentTunnels();
+            runInUIThread(new Runnable() {
+               @Override
+               public void run()
+               {
+                  viewer.setInput(tunnels);
+               }
+            });
+         }
+         
+         @Override
+         protected String getErrorMessage()
+         {
+            return "Cannot unbind tunnel";
+         }
+      }.start();
+   }
+   
+   /**
+    * Unbind tunnel
+    */
+   private void unbindTunnel()
+   {
+      IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+      if (selection.isEmpty())
+         return;
+      
+      if (!MessageDialogHelper.openQuestion(getSite().getShell(), "Unbind Tunnel", "Selected tunnels will be unbound. Are you sure?"))
+         return;
+      
+      final Object[] tunnels = selection.toArray();
+      final NXCSession session = ConsoleSharedData.getSession();
+      new ConsoleJob("Unbind tunnels", this, Activator.PLUGIN_ID, null) {
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            for(Object o : tunnels)
+            {
+               AgentTunnel t = (AgentTunnel)o;
+               if (!t.isBound())
+                  continue;
+               session.unbindAgentTunnel(t.getNodeId());
+            }
+
+            final List<AgentTunnel> tunnels = session.getAgentTunnels();
+            runInUIThread(new Runnable() {
+               @Override
+               public void run()
+               {
+                  viewer.setInput(tunnels);
+               }
+            });
+         }
+         
+         @Override
+         protected String getErrorMessage()
+         {
+            return "Cannot unbind tunnel";
+         }
+      }.start();
+   }
+}
diff --git a/src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/helpers/TunnelListLabelProvider.java b/src/java/netxms-eclipse/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/helpers/TunnelListLabelProvider.java
new file mode 100644 (file)
index 0000000..360eda0
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.agentmanager.views.helpers;
+
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.netxms.client.AgentTunnel;
+import org.netxms.ui.eclipse.agentmanager.views.TunnelManager;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+
+/**
+ * Label provider for tunnel list
+ */
+public class TunnelListLabelProvider extends LabelProvider implements ITableLabelProvider, IColorProvider
+{
+   private static final Color COLOR_BOUND = new Color(Display.getDefault(), new RGB(26, 88, 0));
+   private static final Color COLOR_UNBOUND = new Color(Display.getDefault(), new RGB(199, 83, 0));
+   
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+    */
+   @Override
+   public Image getColumnImage(Object element, int columnIndex)
+   {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+    */
+   @Override
+   public String getColumnText(Object element, int columnIndex)
+   {
+      AgentTunnel t = (AgentTunnel)element;
+      switch(columnIndex)
+      {
+         case TunnelManager.COL_AGENT_VERSION:
+            return t.getAgentVersion();
+         case TunnelManager.COL_CHANNELS:
+            return t.isBound() ? Integer.toString(t.getActiveChannelCount()) : "";
+         case TunnelManager.COL_ID:
+            return Integer.toString(t.getId());
+         case TunnelManager.COL_IP_ADDRESS:
+            return t.getAddress().getHostAddress();
+         case TunnelManager.COL_NODE:
+            return t.isBound() ? ConsoleSharedData.getSession().getObjectName(t.getNodeId()) : "";
+         case TunnelManager.COL_PLATFORM:
+            return t.getPlatformName();
+         case TunnelManager.COL_STATE:
+            return t.isBound() ? "Bound" : "Unbound";
+         case TunnelManager.COL_SYSINFO:
+            return t.getSystemInformation();
+         case TunnelManager.COL_SYSNAME:
+            return t.getSystemName();
+      }
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
+    */
+   @Override
+   public Color getForeground(Object element)
+   {
+      return ((AgentTunnel)element).isBound() ? COLOR_BOUND : COLOR_UNBOUND;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object)
+    */
+   @Override
+   public Color getBackground(Object element)
+   {
+      return null;
+   }
+}
index cd59dbb..3e854d3 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ** NetXMS - Network Management System
 ** NetXMS Foundation Library
-** Copyright (C) 2003-2016 Victor Kirhenshtein
+** Copyright (C) 2003-2017 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU Lesser General Public License as published
@@ -252,7 +252,7 @@ TCHAR LIBNETXMS_EXPORTABLE *NXCPMessageCodeName(WORD code, TCHAR *pszBuffer)
                _T("CMD_GET_PERSISTENT_STORAGE"),
                _T("CMD_DELETE_PSTORAGE_VALUE"),
                _T("CMD_UPDATE_PSTORAGE_VALUE"),
-               _T("CMD_GET_UNBOUND_AGENT_TUNNELS"),
+               _T("CMD_GET_AGENT_TUNNELS"),
                _T("CMD_BIND_AGENT_TUNNEL"),
                _T("CMD_REQUEST_CERTIFICATE"),
                _T("CMD_NEW_CERTIFICATE"),
index 667a0d1..4ab98db 100644 (file)
@@ -75,7 +75,7 @@ void FillComponentsMessage(NXCPMessage *msg);
 void GetPredictionEngines(NXCPMessage *msg);
 bool GetPredictedData(ClientSession *session, const NXCPMessage *request, NXCPMessage *response, DataCollectionTarget *dcTarget);
 
-void GetUnboundAgentTunnels(NXCPMessage *msg);
+void GetAgentTunnels(NXCPMessage *msg);
 UINT32 BindAgentTunnel(UINT32 tunnelId, UINT32 nodeId);
 UINT32 UnbindAgentTunnel(UINT32 nodeId);
 
@@ -1463,8 +1463,8 @@ void ClientSession::processingThread()
          case CMD_DELETE_REPOSITORY:
             CALL_IN_NEW_THREAD(deleteRepository, pMsg);
             break;
-         case CMD_GET_UNBOUND_AGENT_TUNNELS:
-            getUnboundAgentTunnels(pMsg);
+         case CMD_GET_AGENT_TUNNELS:
+            getAgentTunnels(pMsg);
             break;
          case CMD_BIND_AGENT_TUNNEL:
             bindAgentTunnel(pMsg);
@@ -14199,21 +14199,21 @@ void ClientSession::getPredictedData(NXCPMessage *request)
 }
 
 /**
- * Get list of unbound agent tunnels
+ * Get list of agent tunnels
  */
-void ClientSession::getUnboundAgentTunnels(NXCPMessage *request)
+void ClientSession::getAgentTunnels(NXCPMessage *request)
 {
    NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    if (m_dwSystemAccess & SYSTEM_ACCESS_REGISTER_AGENTS)
    {
-      GetUnboundAgentTunnels(&msg);
+      GetAgentTunnels(&msg);
       msg.setField(VID_RCC, RCC_SUCCESS);
-      writeAuditLog(AUDIT_SYSCFG, true, 0, _T("Read list of unbound agent tunnels"));
+      writeAuditLog(AUDIT_SYSCFG, true, 0, _T("Read list of agent tunnels"));
    }
    else
    {
       msg.setField(VID_RCC, RCC_ACCESS_DENIED);
-      writeAuditLog(AUDIT_SYSCFG, false, 0, _T("Access denied on reading list of unbound agent tunnels"));
+      writeAuditLog(AUDIT_SYSCFG, false, 0, _T("Access denied on reading list of agent tunnels"));
    }
    sendMessage(&msg);
 }
index 5ed39f1..a2ab923 100644 (file)
@@ -160,18 +160,28 @@ UINT32 UnbindAgentTunnel(UINT32 nodeId)
 }
 
 /**
- * Get list of unbound agent tunnels into NXCP message
+ * Get list of agent tunnels into NXCP message
  */
-void GetUnboundAgentTunnels(NXCPMessage *msg)
+void GetAgentTunnels(NXCPMessage *msg)
 {
    s_tunnelListLock.lock();
    UINT32 fieldId = VID_ELEMENT_LIST_BASE;
+
    for(int i = 0; i < s_unboundTunnels.size(); i++)
    {
       ((AgentTunnel *)s_unboundTunnels.get(i))->fillMessage(msg, fieldId);
-      fieldId += 10;
+      fieldId += 64;
+   }
+
+   Iterator<AgentTunnel> *it = s_boundTunnels.iterator();
+   while(it->hasNext())
+   {
+      it->next()->fillMessage(msg, fieldId);
+      fieldId += 64;
    }
-   msg->setField(VID_NUM_ELEMENTS, (UINT32)s_unboundTunnels.size());
+   delete it;
+
+   msg->setField(VID_NUM_ELEMENTS, (UINT32)(s_unboundTunnels.size() + s_boundTunnels.size()));
    s_tunnelListLock.unlock();
 }
 
index 9030ab9..2016d38 100644 (file)
@@ -757,7 +757,7 @@ private:
    void addRepository(NXCPMessage *request);
    void modifyRepository(NXCPMessage *request);
    void deleteRepository(NXCPMessage *request);
-   void getUnboundAgentTunnels(NXCPMessage *request);
+   void getAgentTunnels(NXCPMessage *request);
    void bindAgentTunnel(NXCPMessage *request);
    void unbindAgentTunnel(NXCPMessage *request);
    void getPredictionEngines(NXCPMessage *request);
index 6f0c49a..a14296a 100644 (file)
@@ -1,7 +1,9 @@
 action.openAgentConfigManager=Agent Configurations
 action.openPackageManager=Package Manager
+action.openTunnelManager=Agent Tunnel Manager
 actionDescription.openAgentConfigManager=Open agent configuration manager
 actionDescription.openPackageManager=Open package manager
+actionDescription.openTunnelManager=Open agent tunnel manager
 actionSet.AgentManagement=Agent Management
 menu.EditConfig=Edit agent's configuration file
 menu.TakeScreenshot=Take screenshot
@@ -10,3 +12,4 @@ view.AgentConfigManager=Agent Configuration Manager
 view.PackageDeploymentMonitor=Package Deployment Monitor
 view.PackageManager=Package Manager
 view.Screenshot=Screenshot
+view.TunnelManager=Agent Tunnel Manager
diff --git a/webui/webapp/AgentManager/icons/tunnel_manager.png b/webui/webapp/AgentManager/icons/tunnel_manager.png
new file mode 100644 (file)
index 0000000..a44fdd3
Binary files /dev/null and b/webui/webapp/AgentManager/icons/tunnel_manager.png differ
index 5528888..522b6e1 100644 (file)
             name="%view.Screenshot"
             restorable="false">
       </view>
+      <view
+            allowMultiple="false"
+            class="org.netxms.ui.eclipse.agentmanager.views.TunnelManager"
+            icon="icons/tunnel_manager.png"
+            id="org.netxms.ui.eclipse.agentmanager.views.TunnelManager"
+            name="Agent Tunnel Manager"
+            restorable="true">
+      </view>
    </extension>
    <extension
          point="org.eclipse.ui.popupMenus">
                toolbarPath="config/additions"
                tooltip="%actionDescription.openPackageManager">
          </action>
+         <action
+               class="org.netxms.ui.eclipse.agentmanager.actions.OpenTunnelManager"
+               definitionId="org.netxms.ui.eclipse.agentmanager.commands.open_tunnel_manager"
+               icon="icons/tunnel_manager.png"
+               id="org.netxms.ui.eclipse.agentmanager.actions.open_tunnel_manager"
+               label="%action.openTunnelManager"
+               menubarPath="config/additions"
+               style="push"
+               toolbarPath="config/additions"
+               tooltip="%actionDescription.openTunnelManager">
+         </action>
       </actionSet>
    </extension>
    <extension
             id="org.netxms.ui.eclipse.agentmanager.commands.copy_screenshot"
             name="Copy screenshot">
       </command>
+      <command
+            categoryId="org.netxms.ui.eclipse.console.category.views"
+            description="%actionDescription.openTunnelManager"
+            id="org.netxms.ui.eclipse.agentmanager.commands.open_tunnel_manager"
+            name="%action.openTunnelManager">
+      </command>
    </extension>
    <extension
          point="org.eclipse.ui.contexts">
index f393af3..57d2077 100644 (file)
  */
 package org.netxms.ui.eclipse.agentmanager.actions;
 
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-import org.eclipse.ui.PartInitException;
-import org.netxms.ui.eclipse.agentmanager.Messages;
+import org.netxms.ui.eclipse.actions.OpenView;
 import org.netxms.ui.eclipse.agentmanager.views.PackageManager;
-import org.netxms.ui.eclipse.tools.MessageDialogHelper;
 
-public class OpenPackageManager implements IWorkbenchWindowActionDelegate
+/**
+ * Open package manager view
+ */
+public class OpenPackageManager extends OpenView
 {
-       private IWorkbenchWindow window;
-       
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
-        */
-       @Override
-       public void dispose()
-       {
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
-        */
-       @Override
-       public void init(IWorkbenchWindow window)
-       {
-               this.window = window;
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
-        */
-       @Override
-       public void run(IAction action)
-       {
-               if(window != null)
-               {       
-                       try 
-                       {
-                               window.getActivePage().showView(PackageManager.ID);
-                       } 
-                       catch (PartInitException e) 
-                       {
-                               MessageDialogHelper.openError(window.getShell(), Messages.get().OpenPackageManager_Error, Messages.get().OpenPackageManager_ErrorOpenView + e.getMessage());
-                       }
-               }
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
-        */
-       @Override
-       public void selectionChanged(IAction action, ISelection selection)
-       {
-       }
+   /* (non-Javadoc)
+    * @see org.netxms.ui.eclipse.actions.OpenView#getViewId()
+    */
+   @Override
+   protected String getViewId()
+   {
+      return PackageManager.ID;
+   }
 }
diff --git a/webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenTunnelManager.java b/webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/actions/OpenTunnelManager.java
new file mode 100644 (file)
index 0000000..93e3870
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.agentmanager.actions;
+
+import org.netxms.ui.eclipse.actions.OpenView;
+import org.netxms.ui.eclipse.agentmanager.views.TunnelManager;
+
+/**
+ * Open tunnel manager view
+ */
+public class OpenTunnelManager extends OpenView
+{
+   /* (non-Javadoc)
+    * @see org.netxms.ui.eclipse.actions.OpenView#getViewId()
+    */
+   @Override
+   protected String getViewId()
+   {
+      return TunnelManager.ID;
+   }
+}
index 8ccdac3..6ed8ae5 100644 (file)
@@ -160,7 +160,7 @@ public class PackageManager extends ViewPart
         */
        private void createActions()
        {
-               actionRefresh = new RefreshAction() {
+               actionRefresh = new RefreshAction(this) {
                        @Override
                        public void run()
                        {
@@ -266,7 +266,7 @@ public class PackageManager extends ViewPart
         */
        private void refresh()
        {
-               final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
+               final NXCSession session = ConsoleSharedData.getSession();
                new ConsoleJob(Messages.get().PackageManager_LoadPkgList, this, Activator.PLUGIN_ID, null) {
                        @Override
                        protected void runInternal(IProgressMonitor monitor) throws Exception
diff --git a/webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/TunnelManager.java b/webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/TunnelManager.java
new file mode 100644 (file)
index 0000000..a370df4
--- /dev/null
@@ -0,0 +1,316 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.agentmanager.views;
+
+import java.util.List;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.part.ViewPart;
+import org.netxms.client.AgentTunnel;
+import org.netxms.client.NXCSession;
+import org.netxms.ui.eclipse.actions.RefreshAction;
+import org.netxms.ui.eclipse.agentmanager.Activator;
+import org.netxms.ui.eclipse.agentmanager.views.helpers.TunnelListLabelProvider;
+import org.netxms.ui.eclipse.jobs.ConsoleJob;
+import org.netxms.ui.eclipse.objectbrowser.dialogs.ObjectSelectionDialog;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+import org.netxms.ui.eclipse.tools.MessageDialogHelper;
+import org.netxms.ui.eclipse.widgets.SortableTableViewer;
+
+/**
+ * Tunnel manager view
+ */
+public class TunnelManager extends ViewPart
+{
+   public static final String ID = "org.netxms.ui.eclipse.agentmanager.views.TunnelManager";
+   
+   public static final int COL_ID = 0;
+   public static final int COL_STATE = 1;
+   public static final int COL_NODE = 2;
+   public static final int COL_IP_ADDRESS = 3;
+   public static final int COL_CHANNELS = 4;
+   public static final int COL_SYSNAME = 5;
+   public static final int COL_PLATFORM = 6;
+   public static final int COL_SYSINFO = 7;
+   public static final int COL_AGENT_VERSION = 8;
+   
+   private SortableTableViewer viewer;
+   private Action actionRefresh;
+   private Action actionBind;
+   private Action actionUnbind;
+   
+   /* (non-Javadoc)
+    * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+    */
+   @Override
+   public void createPartControl(Composite parent)
+   {
+      final String[] names = { "ID", "State", "Node", "IP address", "Channels", "System name", "Platform", "System information", "Agent version" };
+      final int[] widths = { 80, 80, 140, 150, 80, 150, 150, 300, 150 };
+      viewer = new SortableTableViewer(parent, names, widths, 0, SWT.UP, SWT.FULL_SELECTION);
+      viewer.setContentProvider(new ArrayContentProvider());
+      viewer.setLabelProvider(new TunnelListLabelProvider());
+      
+      createActions();
+      contributeToActionBars();
+      createPopupMenu();
+      
+      refresh();
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
+    */
+   @Override
+   public void setFocus()
+   {
+      viewer.getTable().setFocus();
+   }
+
+   /**
+    * Create actions
+    */
+   private void createActions()
+   {
+      actionRefresh = new RefreshAction(this) {
+         @Override
+         public void run()
+         {
+            refresh();
+         }
+      };
+      
+      actionBind = new Action("&Bind to...") {
+         @Override
+         public void run()
+         {
+            bindTunnel();
+         }
+      };
+      
+      actionUnbind = new Action("&Unbind") {
+         @Override
+         public void run()
+         {
+            unbindTunnel();
+         }
+      };
+   }
+
+   /**
+    * Contribute actions to action bars
+    */
+   private void contributeToActionBars()
+   {
+      IActionBars bars = getViewSite().getActionBars();
+      fillLocalPullDown(bars.getMenuManager());
+      fillLocalToolBar(bars.getToolBarManager());
+   }
+
+   /**
+    * Fill local pulldown menu
+    * @param manager menu manager
+    */
+   private void fillLocalPullDown(IMenuManager manager)
+   {
+      manager.add(actionRefresh);
+   }
+
+   /**
+    * Fill local toolbar
+    * @param manager menu manager
+    */
+   private void fillLocalToolBar(IToolBarManager manager)
+   {
+      manager.add(actionRefresh);
+   }
+
+   /**
+    * Create pop-up menu
+    */
+   private void createPopupMenu()
+   {
+      // Create menu manager.
+      MenuManager menuMgr = new MenuManager();
+      menuMgr.setRemoveAllWhenShown(true);
+      menuMgr.addMenuListener(new IMenuListener() {
+         public void menuAboutToShow(IMenuManager mgr)
+         {
+            fillContextMenu(mgr);
+         }
+      });
+
+      // Create menu.
+      Menu menu = menuMgr.createContextMenu(viewer.getControl());
+      viewer.getControl().setMenu(menu);
+
+      // Register menu for extension.
+      getSite().registerContextMenu(menuMgr, viewer);
+   }
+   
+   /**
+    * Fill context menu
+    * @param manager Menu manager
+    */
+   protected void fillContextMenu(IMenuManager manager)
+   {
+      IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+      if ((selection.size() == 1) && !((AgentTunnel)selection.getFirstElement()).isBound())
+      {
+         manager.add(actionBind);
+      }
+      else
+      {
+         for(Object o : selection.toList())
+         {
+            if (((AgentTunnel)o).isBound())
+            {
+               manager.add(actionUnbind);
+               break;
+            }
+         }
+      }
+   }
+   
+   /**
+    * Refresh view
+    */
+   private void refresh()
+   {
+      final NXCSession session = ConsoleSharedData.getSession();
+      new ConsoleJob("Get list of active agent tunnels", this, Activator.PLUGIN_ID, null) {
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            final List<AgentTunnel> tunnels = session.getAgentTunnels();
+            runInUIThread(new Runnable() {
+               @Override
+               public void run()
+               {
+                  viewer.setInput(tunnels);
+               }
+            });
+         }
+         
+         @Override
+         protected String getErrorMessage()
+         {
+            return "Cannot get list of active agent tunnels";
+         }
+      }.start();
+   }
+   
+   /**
+    * Bind tunnel to node
+    */
+   private void bindTunnel()
+   {
+      IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+      if (selection.size() != 1)
+         return;
+      
+      final AgentTunnel tunnel = (AgentTunnel)selection.getFirstElement();
+      if (tunnel.isBound())
+         return;
+      
+      ObjectSelectionDialog dlg = new ObjectSelectionDialog(getSite().getShell(), null, ObjectSelectionDialog.createNodeSelectionFilter(false));
+      if (dlg.open() != Window.OK)
+         return;      
+      final long nodeId = dlg.getSelectedObjects().get(0).getObjectId();
+      
+      final NXCSession session = ConsoleSharedData.getSession();
+      new ConsoleJob("Bind tunnels", this, Activator.PLUGIN_ID, null) {
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            session.bindAgentTunnel(tunnel.getId(), nodeId);
+
+            final List<AgentTunnel> tunnels = session.getAgentTunnels();
+            runInUIThread(new Runnable() {
+               @Override
+               public void run()
+               {
+                  viewer.setInput(tunnels);
+               }
+            });
+         }
+         
+         @Override
+         protected String getErrorMessage()
+         {
+            return "Cannot unbind tunnel";
+         }
+      }.start();
+   }
+   
+   /**
+    * Unbind tunnel
+    */
+   private void unbindTunnel()
+   {
+      IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+      if (selection.isEmpty())
+         return;
+      
+      if (!MessageDialogHelper.openQuestion(getSite().getShell(), "Unbind Tunnel", "Selected tunnels will be unbound. Are you sure?"))
+         return;
+      
+      final Object[] tunnels = selection.toArray();
+      final NXCSession session = ConsoleSharedData.getSession();
+      new ConsoleJob("Unbind tunnels", this, Activator.PLUGIN_ID, null) {
+         @Override
+         protected void runInternal(IProgressMonitor monitor) throws Exception
+         {
+            for(Object o : tunnels)
+            {
+               AgentTunnel t = (AgentTunnel)o;
+               if (!t.isBound())
+                  continue;
+               session.unbindAgentTunnel(t.getNodeId());
+            }
+
+            final List<AgentTunnel> tunnels = session.getAgentTunnels();
+            runInUIThread(new Runnable() {
+               @Override
+               public void run()
+               {
+                  viewer.setInput(tunnels);
+               }
+            });
+         }
+         
+         @Override
+         protected String getErrorMessage()
+         {
+            return "Cannot unbind tunnel";
+         }
+      }.start();
+   }
+}
diff --git a/webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/helpers/TunnelListLabelProvider.java b/webui/webapp/AgentManager/src/org/netxms/ui/eclipse/agentmanager/views/helpers/TunnelListLabelProvider.java
new file mode 100644 (file)
index 0000000..360eda0
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2017 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.agentmanager.views.helpers;
+
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.netxms.client.AgentTunnel;
+import org.netxms.ui.eclipse.agentmanager.views.TunnelManager;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+
+/**
+ * Label provider for tunnel list
+ */
+public class TunnelListLabelProvider extends LabelProvider implements ITableLabelProvider, IColorProvider
+{
+   private static final Color COLOR_BOUND = new Color(Display.getDefault(), new RGB(26, 88, 0));
+   private static final Color COLOR_UNBOUND = new Color(Display.getDefault(), new RGB(199, 83, 0));
+   
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+    */
+   @Override
+   public Image getColumnImage(Object element, int columnIndex)
+   {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+    */
+   @Override
+   public String getColumnText(Object element, int columnIndex)
+   {
+      AgentTunnel t = (AgentTunnel)element;
+      switch(columnIndex)
+      {
+         case TunnelManager.COL_AGENT_VERSION:
+            return t.getAgentVersion();
+         case TunnelManager.COL_CHANNELS:
+            return t.isBound() ? Integer.toString(t.getActiveChannelCount()) : "";
+         case TunnelManager.COL_ID:
+            return Integer.toString(t.getId());
+         case TunnelManager.COL_IP_ADDRESS:
+            return t.getAddress().getHostAddress();
+         case TunnelManager.COL_NODE:
+            return t.isBound() ? ConsoleSharedData.getSession().getObjectName(t.getNodeId()) : "";
+         case TunnelManager.COL_PLATFORM:
+            return t.getPlatformName();
+         case TunnelManager.COL_STATE:
+            return t.isBound() ? "Bound" : "Unbound";
+         case TunnelManager.COL_SYSINFO:
+            return t.getSystemInformation();
+         case TunnelManager.COL_SYSNAME:
+            return t.getSystemName();
+      }
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
+    */
+   @Override
+   public Color getForeground(Object element)
+   {
+      return ((AgentTunnel)element).isBound() ? COLOR_BOUND : COLOR_UNBOUND;
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object)
+    */
+   @Override
+   public Color getBackground(Object element)
+   {
+      return null;
+   }
+}