/********************************************************************************************* * Copyright (c) 2014-2015 Software Behaviour Analysis Lab, Concordia University, Montreal, Canada * * All rights reserved. This program and the accompanying materials * are made available under the terms of Eclipse Public License v1.0 License which * accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Syed Shariyar Murtaza -- Initial design and implementation **********************************************************************************************/ package org.eclipse.tracecompass.totalads.ui.live; import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.tracecompass.totalads.algorithms.AlgorithmUtility; import org.eclipse.tracecompass.totalads.algorithms.IDetectionAlgorithm; import org.eclipse.tracecompass.totalads.exceptions.TotalADSGeneralException; import org.eclipse.tracecompass.totalads.ui.io.DirectoryBrowser; import org.eclipse.tracecompass.totalads.ui.live.BackgroundLiveMonitor; import org.eclipse.tracecompass.totalads.ui.live.LiveXYChart; import org.eclipse.tracecompass.totalads.ui.live.Messages; import org.eclipse.tracecompass.totalads.ui.results.ResultsAndFeedback; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; /** * This class creates the GUI elements/widgets for live diagnosis using SSH. * LTTng tracing can be started on a system, and both live training and testing * can be done simultaneously. * * @author <p> * Syed Shariyar Murtaza justsshary@hotmail.com * </p> * */ public class LiveMonitor { private Text fTxtUserAtHost; private Combo fCmbSnapshot; private Combo fCmbInterval; private Text fTxtPort; private Text fPassword; private ResultsAndFeedback fResultsAndFeedback; private Button fBtnStart; private Button fBtnStop; private Text fTxtTraces; private BackgroundLiveMonitor fLiveExecutor; private LiveXYChart fLiveChart; private Button fBtnTrainingAndEval; private Button fBtnTesting; private HashSet<String> fModelsList; private String msgTitle="TotalADS"; //$NON-NLS-1$ /** * Constructor for the Live Monitor */ public LiveMonitor() { fModelsList = new HashSet<>(); } /** * Creates GUI widgets * * @param compParent * Composite */ public void createControls(Composite compParent) { ScrolledComposite scrolCompAnom = new ScrolledComposite(compParent, SWT.H_SCROLL | SWT.V_SCROLL); Composite comptbItmLive = new Composite(scrolCompAnom, SWT.NONE); // Designing the Layout of the GUI Items for the LiveMonitor Tab Item GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); gridData.horizontalSpan = 1; comptbItmLive.setLayoutData(gridData); comptbItmLive.setLayout(new GridLayout(2, false)); // ///////////////////////////////////////////////////////////////////////// // Creating GUI widgets for SSH parameters // ///////////////////////////////////////////////////////////////// // Create GUI elements for SSH Configuration selectHostUsingSSH(comptbItmLive); trainingAndTesting(comptbItmLive); traceStorage(comptbItmLive); // //////////////////////////////////////////////////////////////////// // Creating GUI widgets for buttons // //////////////////////////////////////////////////////////////// Composite compButtons = new Composite(comptbItmLive, SWT.NONE); compButtons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1)); compButtons.setLayout(new GridLayout(5, false)); fBtnStart = new Button(compButtons, SWT.BORDER); fBtnStart.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, true, false, 1, 1)); fBtnStart.setText(Messages.LiveMonitor_Start); fBtnStop = new Button(compButtons, SWT.BORDER); fBtnStop.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1)); fBtnStop.setText(Messages.LiveMonitor_Stop); fBtnStop.setEnabled(false); // Adjust settings for scrollable LiveMonitor Tab Item scrolCompAnom.setContent(comptbItmLive); // Set the minimum size scrolCompAnom.setMinSize(200, 200); // Expand both horizontally and vertically scrolCompAnom.setExpandHorizontal(true); scrolCompAnom.setExpandVertical(true); addHandlers(); } /** * Creates GUI widgets for a selection of traces and trace types * * @param compParent * Composite of LiveMonitor */ private void selectHostUsingSSH(Composite compParent) { /** * Group trace selection */ Group grpSSHConfig = new Group(compParent, SWT.NONE); grpSSHConfig.setText(Messages.LiveMonitor_SshConfig); grpSSHConfig.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 2)); grpSSHConfig.setLayout(new GridLayout(2, false)); // ///////////////////////////////////////////// // /User name, password, and port // //////////////////////////////////////////// Composite compUserPasPort = new Composite(grpSSHConfig, SWT.NONE); compUserPasPort.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); compUserPasPort.setLayout(new GridLayout(3, false)); Label userAtHost = new Label(compUserPasPort, SWT.NONE); userAtHost.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 1, 1)); userAtHost.setText(Messages.LiveMonitor_UserAtHost); Label lblPassword = new Label(compUserPasPort, SWT.NONE); lblPassword.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 1, 1)); lblPassword.setText(Messages.LiveMonitor_Password); Label lblPort = new Label(compUserPasPort, SWT.NONE); lblPort.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 1, 1)); lblPort.setText(Messages.LiveMonitor_Port); fTxtUserAtHost = new Text(compUserPasPort, SWT.BORDER); fTxtUserAtHost.setEnabled(true); fTxtUserAtHost.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); fTxtUserAtHost.setText(System.getProperty("user.name") + "@localhost"); //$NON-NLS-1$ //$NON-NLS-2$ fPassword = new Text(compUserPasPort, SWT.BORDER | SWT.PASSWORD); fPassword.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); fPassword.setText("123456"); //$NON-NLS-1$ fTxtPort = new Text(compUserPasPort, SWT.BORDER); fTxtPort.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); fTxtPort.setText("22"); //$NON-NLS-1$ // /////// // /SSH Password and Private Key: Currently disabling this to provide it // in the next version // /////// /* * Group grpPrivacy = new Group(grpSSHConfig, SWT.NONE); * grpPrivacy.setText("SSH Password/Pvt. Key"); * * grpPrivacy.setLayoutData(new * GridData(SWT.FILL,SWT.FILL,false,false,3,2)); * grpPrivacy.setLayout(new GridLayout(3,false)); * * btnPassword = new Button(grpPrivacy, SWT.RADIO); * btnPassword.setText("Enter Password"); btnPassword.setLayoutData(new * GridData(SWT.FILL,SWT.TOP,true, false,1,1)); * btnPassword.setSelection(true); * * btnPvtKey = new Button(grpPrivacy, SWT.RADIO); * btnPvtKey.setText("Select Private Key"); btnPvtKey.setLayoutData(new * GridData(SWT.FILL,SWT.TOP,true, false,2,1)); * * * txtPassword=new Text(grpPrivacy,SWT.BORDER|SWT.PASSWORD); * txtPassword.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, * false,1,1)); txtPassword.setText("grt_654321"); * * txtPvtKey=new Text(grpPrivacy,SWT.BORDER); * txtPvtKey.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, * false,1,1)); //txtPvtKey.setText(""); txtPvtKey.setEnabled(false); * * trcbrowser=new FileBrowser(grpPrivacy, txtPvtKey, new * GridData(SWT.RIGHT, SWT.TOP, false, false)); * trcbrowser.disableBrowsing(); */ // //////// // /End SSH password and private name // //// // ///////////// // Duration and Port // //////// Composite compDuration = new Composite(grpSSHConfig, SWT.NONE); compDuration.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); compDuration.setLayout(new GridLayout(2, false)); Label lblSnapshotDuration = new Label(compDuration, SWT.NONE); lblSnapshotDuration.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 1, 1)); lblSnapshotDuration.setText(Messages.LiveMonitor_SnapshotDuration); Label lblIntervalDuration = new Label(compDuration, SWT.NONE); lblIntervalDuration.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 1, 1)); lblIntervalDuration.setText(Messages.LiveMonitor_SnapshotInterval); fCmbSnapshot = new Combo(compDuration, SWT.NONE | SWT.READ_ONLY); fCmbSnapshot.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false, 1, 1)); fCmbSnapshot.add("5"); //$NON-NLS-1$ fCmbSnapshot.add("10"); //$NON-NLS-1$ fCmbSnapshot.add("15"); //$NON-NLS-1$ fCmbSnapshot.add("20"); //$NON-NLS-1$ fCmbSnapshot.add("35"); //$NON-NLS-1$ fCmbSnapshot.add("60"); //$NON-NLS-1$ fCmbSnapshot.select(0); fCmbInterval = new Combo(compDuration, SWT.NONE | SWT.READ_ONLY); fCmbInterval.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false, 1, 1)); fCmbInterval.add("0"); //$NON-NLS-1$ fCmbInterval.add("1"); //$NON-NLS-1$ fCmbInterval.add("3"); //$NON-NLS-1$ fCmbInterval.add("5"); //$NON-NLS-1$ fCmbInterval.add("7"); //$NON-NLS-1$ fCmbInterval.add("10"); //$NON-NLS-1$ fCmbInterval.add("15"); //$NON-NLS-1$ fCmbInterval.add("20"); //$NON-NLS-1$ fCmbInterval.add("30"); //$NON-NLS-1$ fCmbInterval.select(0); /** * End group trace selection */ } /** * Training and Testing Widgets * * @param compParent * Parent composite */ public void trainingAndTesting(Composite compParent) { // /////// // /Training and Evaluation // /////// Group grpTrainingAndEval = new Group(compParent, SWT.NONE); grpTrainingAndEval.setText(Messages.LiveMonitor_EvalType); grpTrainingAndEval.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); grpTrainingAndEval.setLayout(new GridLayout(2, false)); fBtnTrainingAndEval = new Button(grpTrainingAndEval, SWT.NONE | SWT.RADIO); fBtnTrainingAndEval.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); fBtnTrainingAndEval.setText(Messages.LiveMonitor_TrainAndTest); fBtnTesting = new Button(grpTrainingAndEval, SWT.NONE | SWT.RADIO); fBtnTesting.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); fBtnTesting.setText(Messages.LiveMonitor_Testing); fBtnTesting.setSelection(true); } /** * Trace storage widgets * * @param compParent * Composite */ private void traceStorage(Composite compParent) { // /////// // /Training and Evaluation // /////// Group grpStorage = new Group(compParent, SWT.NONE); grpStorage.setText(Messages.LiveMonitor_StorageDir); grpStorage.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); grpStorage.setLayout(new GridLayout(3, false)); fTxtTraces = new Text(grpStorage, SWT.BORDER); fTxtTraces.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); new DirectoryBrowser(grpStorage, fTxtTraces, new GridData(SWT.RIGHT, SWT.TOP, false, false)); } /** * Handlers */ private void addHandlers() { /** * */ fBtnStart.addMouseListener(new MouseAdapter() { @Override public void mouseUp(MouseEvent e) { if (findInvalidSSettings() == false && inValidModel() == false) { fResultsAndFeedback.clearData(); String password = ""; //$NON-NLS-1$ String privateKey = ""; //$NON-NLS-1$ Boolean isTrainAndEval = false; int port = Integer.parseInt(fTxtPort.getText()); int snapshotDuration = Integer.parseInt(fCmbSnapshot.getItem(fCmbSnapshot.getSelectionIndex())); int snapshotIntervals = Integer.parseInt(fCmbInterval.getItem(fCmbInterval.getSelectionIndex())); /* * // Will be enabled in the next version if * (btnPassword.getSelection()) * password=txtPassword.getText(); else if * (btnPvtKey.getSelection()) * privateKey=txtPvtKey.getText(); */ // so using the following for this version password = fPassword.getText(); if (fBtnTrainingAndEval.getSelection()) { isTrainAndEval = true; } else if (fBtnTesting.getSelection()) { isTrainAndEval = false; } fBtnStart.setEnabled(false); fBtnStop.setEnabled(true); fLiveExecutor = new BackgroundLiveMonitor (fTxtUserAtHost.getText(), password, null, privateKey, port, snapshotDuration, snapshotIntervals, fBtnStart, fBtnStop, fModelsList, fResultsAndFeedback, fLiveChart, fTxtTraces.getText(), isTrainAndEval); ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(fLiveExecutor); executor.shutdown(); } } }); /** * Stop button event handler */ fBtnStop.addMouseListener(new MouseAdapter() { @Override public void mouseUp(MouseEvent e) { fLiveExecutor.stopMonitoring(); } }); // **** Pvt name button handler: Will be enabled in the next version /* * btnPvtKey.addSelectionListener(new SelectionAdapter() { * * @Override public void widgetSelected(SelectionEvent e) { * trcbrowser.enableBrowsing(); txtPvtKey.setEnabled(true); * txtPassword.setEnabled(false); txtPassword.setText(""); } }); */ // **** Password button name handler /* * btnPassword.addSelectionListener(new SelectionAdapter() { * * @Override public void widgetSelected(SelectionEvent e) { * * txtPvtKey.setEnabled(false); txtPvtKey.setText(""); * trcbrowser.disableBrowsing(); txtPassword.setEnabled(true); } }); */ } /** * Validates the fields before execution * * @return */ private Boolean findInvalidSSettings() { String msg = ""; //$NON-NLS-1$ if (fTxtUserAtHost.getText().isEmpty()) { msg = Messages.LiveMonitor_EmptyHost; } else if (fPassword.getText().isEmpty()) { msg = Messages.LiveMonitor_EmptyPassword; } else if (fTxtPort.getText().isEmpty()) { msg = Messages.LiveMonitor_EmptyPort; } else if (fModelsList.size() <= 0) { msg = Messages.LiveMonitor_SelModel; } else if (fTxtTraces.getText().isEmpty()) { msg = Messages.LiveMonitor_SelDirForSotrage; } else { try { Integer.parseInt(fTxtPort.getText()); } catch (Exception ex) { msg = Messages.LiveMonitor_IntegerPort; } if (msg.isEmpty()) { File file = new File(fTxtTraces.getText() + File.separator + "tmp"); //$NON-NLS-1$ try { file.createNewFile(); file.delete(); } catch (IOException e) { msg = Messages.LiveMonitor_UnableToWrite; } } } if (!msg.isEmpty()) { MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), msgTitle,msg); return true; } return false; } /** * Checks whether an algorithm of a model supports online training * * @return */ private Boolean inValidModel() { if (fBtnTrainingAndEval.getSelection() == false) { return false; } String exception = ""; //$NON-NLS-1$ Iterator<String> it = fModelsList.iterator(); while (it.hasNext()) { String model = it.next(); try { IDetectionAlgorithm algorithm = AlgorithmUtility.getAlgorithmFromModelName(model); if (!algorithm.isOnlineLearningSupported()) { exception = NLS.bind(Messages.LiveMonitor_NoOnlineLearnSupport, algorithm.getName()); break; } } catch (TotalADSGeneralException e) { exception = e.getMessage(); } } if (exception.isEmpty()) { return false; } MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), msgTitle,exception); return true; } /** * Sets the chart object * * @param chart * Chart object */ public void setLiveChart(LiveXYChart chart) { fLiveChart = chart; } /** * Sets ResultsAndFeedback object * * @param results * Results object */ public void setResultsAndFeedback(ResultsAndFeedback results) { this.fResultsAndFeedback = results; } /** * Updates the selected model list * * @param modelsList * Models' list */ public void updateOnModelSelction(HashSet<String> modelsList) { this.fModelsList = modelsList; } }