Search in sources :

Example 1 with WaitForQueriesToCompleteTask

use of au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask in project constellation by constellation-app.

the class ExecuteListener method handle.

/**
 * Handles the click of the execute button in the data access view.
 * <p/>
 * If the execute button was in the "Go" state then it will iterate through
 * all the tabs and run the enabled and valid plugins.
 * <p/>
 * If the execute button was in the "Stop" state then cancel any running plugins.
 *
 * @param event the event triggered by clicking the execute button
 */
@Override
public void handle(final ActionEvent event) {
    // When no graph present, create a new one
    if (DataAccessPaneState.getCurrentGraphId() == null && dataAccessPane.getDataAccessTabPane().hasActiveAndValidPlugins()) {
        // Create new graph
        final NewDefaultSchemaGraphAction graphAction = new NewDefaultSchemaGraphAction();
        graphAction.actionPerformed(null);
        Graph newActiveGraph = null;
        // Wait while graph is getting made
        while (newActiveGraph == null) {
            newActiveGraph = GraphManager.getDefault().getActiveGraph();
        }
        // Set the state's current graph ID to the ID of the new graph
        DataAccessPaneState.setCurrentGraphId(newActiveGraph.getId());
    }
    // Run the selected queries
    final ObservableList<Tab> tabs = dataAccessPane.getDataAccessTabPane().getTabPane().getTabs();
    if (CollectionUtils.isNotEmpty(tabs) && DataAccessPaneState.isExecuteButtonIsGo()) {
        // Change the execute button to "Stop" and do not disable because it is now running
        dataAccessPane.setExecuteButtonToStop(false);
        // Set the state for the current graph state to running queries
        DataAccessPaneState.setQueriesRunning(true);
        // Check to see if an output dir exists. Non exisiting dirs do not prevent the
        // plugins running, just triggers a notification
        final File outputDir = DataAccessPreferenceUtilities.getDataAccessResultsDirEx();
        if (outputDir != null && outputDir.isDirectory()) {
            StatusDisplayer.getDefault().setStatusText(String.format(STATUS_MESSAGE_FORMAT, outputDir.getAbsolutePath()));
        } else if (outputDir != null) {
            NotificationDisplayer.getDefault().notify(RESULTS_DIR_NOT_FOUND_TITLE, ERROR_ICON, String.format(RESULTS_DIR_NOT_FOUND_MSG, outputDir.getAbsolutePath()), null);
        }
        // Save the current data access view state
        PluginExecution.withPlugin(new SimplePlugin(SAVE_STATE_PLUGIN_NAME) {

            @Override
            protected void execute(final PluginGraphs graphs, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException, PluginException {
                DataAccessUtilities.saveDataAccessState(dataAccessPane.getDataAccessTabPane().getTabPane(), GraphNode.getGraph(DataAccessPaneState.getCurrentGraphId()));
            }
        }).executeLater(null);
        // Run the plugins from each tab. The barrier is the plugin run futures
        // from the previous tab. When the tab is run, it has the option to
        // wait for the previous tab to complete.
        List<Future<?>> barrier = null;
        for (final Tab tab : tabs) {
            LOGGER.log(Level.INFO, String.format("Running tab: %s", tab.getText()));
            barrier = DataAccessTabPane.getQueryPhasePane(tab).runPlugins(barrier);
        }
        // Asynchronously start the task that waits for all the plugins to complete.
        // Once they are complete this task will perform cleanup.
        CompletableFuture.runAsync(new WaitForQueriesToCompleteTask(dataAccessPane, DataAccessPaneState.getCurrentGraphId()), dataAccessPane.getParentComponent().getExecutorService());
        LOGGER.info("Plugins run.");
    } else {
        // The execute button is in a "Stop" state. So cancel any running plugins.
        DataAccessPaneState.getRunningPlugins().keySet().forEach(running -> running.cancel(true));
        // Nothing is running now, so change the execute button to "Go".
        dataAccessPane.setExecuteButtonToGo(false);
    }
    // Disables all plugins in the plugin pane
    if (DataAccessPreferenceUtilities.isDeselectPluginsOnExecuteEnabled()) {
        deselectAllPlugins();
    }
}
Also used : Graph(au.gov.asd.tac.constellation.graph.Graph) WaitForQueriesToCompleteTask(au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask) Tab(javafx.scene.control.Tab) PluginGraphs(au.gov.asd.tac.constellation.plugins.PluginGraphs) PluginInteraction(au.gov.asd.tac.constellation.plugins.PluginInteraction) SimplePlugin(au.gov.asd.tac.constellation.plugins.templates.SimplePlugin) CompletableFuture(java.util.concurrent.CompletableFuture) Future(java.util.concurrent.Future) NewDefaultSchemaGraphAction(au.gov.asd.tac.constellation.graph.node.create.NewDefaultSchemaGraphAction) PluginParameters(au.gov.asd.tac.constellation.plugins.parameters.PluginParameters) File(java.io.File)

Example 2 with WaitForQueriesToCompleteTask

use of au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask in project constellation by constellation-app.

the class DataAccessTabPane method runTabs.

/**
 * Run the given range of tabs inclusively. As each tab is run, the jobs from
 * the previous tab are passed so that it can block if necessary until they
 * are complete.
 * <p/>
 * Before returning a {@link WaitForQueriesToCompleteTask} will be started
 * that will deal with the clean up of the run once it is complete.
 *
 * @param firstTab the first tab to be run
 * @param lastTab the last tab to be run
 */
public void runTabs(final int firstTab, final int lastTab) {
    // Change execute button to stop but do not disable
    getDataAccessPane().setExecuteButtonToStop(false);
    // Need to take a copy for when it changes while this thread is still running
    final String activeGraphId = GraphManager.getDefault().getActiveGraph().getId();
    DataAccessPaneState.setQueriesRunning(activeGraphId, true);
    // TODO This was being called every time runPlugins is called but can't
    // see the point..could break!!!
    storeParameterValues();
    List<Future<?>> barrier = null;
    for (int i = firstTab; i <= lastTab; i++) {
        final Tab tab = getTabPane().getTabs().get(i);
        LOGGER.log(Level.INFO, String.format("Running tab: %s", tab.getText()));
        barrier = getQueryPhasePane(tab).runPlugins(barrier);
    }
    CompletableFuture.runAsync(() -> new WaitForQueriesToCompleteTask(getDataAccessPane(), activeGraphId), getDataAccessPane().getParentComponent().getExecutorService());
}
Also used : WaitForQueriesToCompleteTask(au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask) Tab(javafx.scene.control.Tab) CompletableFuture(java.util.concurrent.CompletableFuture) Future(java.util.concurrent.Future)

Example 3 with WaitForQueriesToCompleteTask

use of au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask in project constellation by constellation-app.

the class ExecuteListenerNGTest method handle_sunny_days.

@Test
public void handle_sunny_days() {
    // Set the results directory
    final File tmpDir = new File(System.getProperty("java.io.tmpdir"));
    DataAccessPreferenceUtilities.setDataAccessResultsDir(tmpDir);
    // Setting this to true ensures that active plugins are de-selected at the end
    DataAccessPreferenceUtilities.setDeselectPluginsOnExecute(true);
    // We don't set the current graph ID in the state but ensure that there
    // active and valid plugins in the tab pane so that a new graph is created
    // on the fly
    when(dataAccessTabPane.hasActiveAndValidPlugins()).thenReturn(true);
    graphNodeMockedStatic.when(() -> GraphNode.getGraph(anyString())).thenReturn(activeGraph);
    // Set up our fake tab pane
    final Tab tab1 = mock(Tab.class);
    final Tab tab2 = mock(Tab.class);
    when(tabPane.getTabs()).thenReturn(FXCollections.observableArrayList(tab1, tab2));
    final QueryPhasePane queryPhasePane1 = mock(QueryPhasePane.class);
    final QueryPhasePane queryPhasePane2 = mock(QueryPhasePane.class);
    dataAccessTabPaneMockedStatic.when(() -> DataAccessTabPane.getQueryPhasePane(tab1)).thenReturn(queryPhasePane1);
    dataAccessTabPaneMockedStatic.when(() -> DataAccessTabPane.getQueryPhasePane(tab2)).thenReturn(queryPhasePane2);
    // Tab 1 does not have enabled plugins and tab 2 does. This is testing the deselect
    // plugin code. The deselection should not happen on tab 1 because it has no enabled
    // plugins
    dataAccessTabPaneMockedStatic.when(() -> DataAccessTabPane.tabHasEnabledPlugins(tab1)).thenReturn(false);
    dataAccessTabPaneMockedStatic.when(() -> DataAccessTabPane.tabHasEnabledPlugins(tab2)).thenReturn(true);
    // Because tab 1 is not enabled de-selection should happen on pane 2 and 3, but
    // not pane 1.
    final DataSourceTitledPane dataSourceTitledPane1 = mock(DataSourceTitledPane.class);
    when(queryPhasePane1.getDataAccessPanes()).thenReturn(List.of(dataSourceTitledPane1));
    final DataSourceTitledPane dataSourceTitledPane2 = mock(DataSourceTitledPane.class);
    final DataSourceTitledPane dataSourceTitledPane3 = mock(DataSourceTitledPane.class);
    when(queryPhasePane2.getDataAccessPanes()).thenReturn(List.of(dataSourceTitledPane2, dataSourceTitledPane3));
    // Set up the plugin running. Tab 1 is run first which returns a future. That future
    // is then passed in when tab 2 is run.
    final List<Future<?>> barrier1 = List.of(CompletableFuture.completedFuture("First tab run"));
    doReturn(barrier1).when(queryPhasePane1).runPlugins(null);
    doReturn(null).when(queryPhasePane2).runPlugins(barrier1);
    final ActionEvent event = mock(ActionEvent.class);
    try (MockedConstruction<WaitForQueriesToCompleteTask> waitForMockedConstruction = Mockito.mockConstruction(WaitForQueriesToCompleteTask.class, (waitForMock, cntxt) -> {
        assertEquals(cntxt.arguments(), List.of(dataAccessPane, GRAPH_ID));
    })) {
        executeListener.handle(event);
        // There was not current graph set during the test setup. So we
        // should see one construction of the graph action to create on.
        assertEquals(graphActionMockedConstruction.constructed().size(), 1);
        // Verify the execute button is changed to "Stop" and the status
        // displayer is sent some text describing the action success
        verify(dataAccessPane).setExecuteButtonToStop(false);
        verify(statusDisplayer).setStatusText("Data access results will be written to " + tmpDir.getAbsolutePath());
        // Verify the current state is saved before the plugins are run
        utilitiesMockedStatic.verify(() -> DataAccessUtilities.saveDataAccessState(tabPane, activeGraph));
        verify(pluginExecution).executeLater(null);
        // Verify the plugins are run
        verify(queryPhasePane1).runPlugins(or(anyList(), isNull()));
        verify(queryPhasePane2).runPlugins(or(anyList(), isNull()));
        verify(queryPhasePane1).runPlugins(null);
        verify(queryPhasePane2).runPlugins(barrier1);
        // Verify that the wait and clean up task is started
        assertEquals(waitForMockedConstruction.constructed().size(), 1);
        completableFutureMockedStatic.verify(() -> CompletableFuture.runAsync(same(waitForMockedConstruction.constructed().get(0)), any(ExecutorService.class)));
        // Verify that the correct plugins are de-selected
        verifyNoInteractions(dataSourceTitledPane1);
        verify(dataSourceTitledPane2).validityChanged(false);
        verify(dataSourceTitledPane3).validityChanged(false);
        verifyNoInteractions(event);
        // Verify that the state for the current graph is that queries are running
        assertTrue(DataAccessPaneState.isQueriesRunning());
    }
}
Also used : DataSourceTitledPane(au.gov.asd.tac.constellation.views.dataaccess.panes.DataSourceTitledPane) WaitForQueriesToCompleteTask(au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask) Tab(javafx.scene.control.Tab) QueryPhasePane(au.gov.asd.tac.constellation.views.dataaccess.panes.QueryPhasePane) ActionEvent(javafx.event.ActionEvent) Future(java.util.concurrent.Future) CompletableFuture(java.util.concurrent.CompletableFuture) File(java.io.File) Test(org.testng.annotations.Test)

Example 4 with WaitForQueriesToCompleteTask

use of au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask in project constellation by constellation-app.

the class DataAccessTabPaneNGTest method runTabs.

@Test
public void runTabs() {
    final String graphId = "graphId";
    try (final MockedStatic<GraphManager> graphManagerMockedStatic = Mockito.mockStatic(GraphManager.class);
        final MockedStatic<DataAccessTabPane> datPaneMockedStatic = Mockito.mockStatic(DataAccessTabPane.class);
        final MockedStatic<CompletableFuture> futureMockedStatic = Mockito.mockStatic(CompletableFuture.class, Mockito.CALLS_REAL_METHODS)) {
        // Set up the active graph
        final GraphManager graphManager = mock(GraphManager.class);
        final Graph graph = mock(Graph.class);
        graphManagerMockedStatic.when(GraphManager::getDefault).thenReturn(graphManager);
        when(graphManager.getActiveGraph()).thenReturn(graph);
        when(graph.getId()).thenReturn(graphId);
        // No need to actually call, storeParameterValues. We will just verify
        // that it is called.
        doNothing().when(dataAccessTabPane).storeParameterValues();
        // Set up our fake tab pane
        final TabPane tabPane = mock(TabPane.class);
        final Tab tab1 = mock(Tab.class);
        final Tab tab2 = mock(Tab.class);
        final Tab tab3 = mock(Tab.class);
        final Tab tab4 = mock(Tab.class);
        final Tab tab5 = mock(Tab.class);
        doReturn(tabPane).when(dataAccessTabPane).getTabPane();
        when(tabPane.getTabs()).thenReturn(FXCollections.observableArrayList(tab1, tab2, tab3, tab4, tab5));
        // No need for a different query pane per tab, so just return the same
        // one for all of them
        final QueryPhasePane queryPhasePane = mock(QueryPhasePane.class);
        datPaneMockedStatic.when(() -> DataAccessTabPane.getQueryPhasePane(any(Tab.class))).thenReturn(queryPhasePane);
        final List<Future<?>> barrier1 = List.of(CompletableFuture.completedFuture("Future 1 Complete"));
        final List<Future<?>> barrier2 = List.of(CompletableFuture.completedFuture("Future 2 Complete"));
        final List<Future<?>> barrier3 = List.of(CompletableFuture.completedFuture("Future 3 Complete"));
        when(queryPhasePane.runPlugins(null)).thenReturn(barrier1);
        when(queryPhasePane.runPlugins(barrier1)).thenReturn(barrier2);
        when(queryPhasePane.runPlugins(barrier2)).thenReturn(barrier3);
        futureMockedStatic.when(() -> CompletableFuture.runAsync(any(Runnable.class), any(ExecutorService.class))).thenAnswer(iom -> {
            WaitForQueriesToCompleteTask task = iom.getArgument(0);
            assertEquals(task.getDataAccessPane(), dataAccessPane);
            assertEquals(task.getGraphId(), graphId);
            return null;
        });
        dataAccessTabPane.runTabs(1, 3);
        verify(dataAccessTabPane).storeParameterValues();
        verify(dataAccessPane).setExecuteButtonToStop(false);
        verify(dataAccessTabPane).storeParameterValues();
        datPaneMockedStatic.verify(() -> DataAccessTabPane.getQueryPhasePane(tab1), never());
        datPaneMockedStatic.verify(() -> DataAccessTabPane.getQueryPhasePane(tab2));
        datPaneMockedStatic.verify(() -> DataAccessTabPane.getQueryPhasePane(tab3));
        datPaneMockedStatic.verify(() -> DataAccessTabPane.getQueryPhasePane(tab4));
        datPaneMockedStatic.verify(() -> DataAccessTabPane.getQueryPhasePane(tab5), never());
        // Verify that run plugins was called only 3 times
        verify(queryPhasePane, times(1)).runPlugins(isNull());
        verify(queryPhasePane, times(2)).runPlugins(any(List.class));
        // Verify that the futures of the last run is passed into the next
        verify(queryPhasePane).runPlugins(null);
        verify(queryPhasePane).runPlugins(barrier1);
        verify(queryPhasePane).runPlugins(barrier2);
        // Verify the query is running state has been set to true
        assertTrue(DataAccessPaneState.isQueriesRunning(graphId));
    }
}
Also used : TabPane(javafx.scene.control.TabPane) GraphManager(au.gov.asd.tac.constellation.graph.manager.GraphManager) WaitForQueriesToCompleteTask(au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask) QueryPhasePane(au.gov.asd.tac.constellation.views.dataaccess.panes.QueryPhasePane) CompletableFuture(java.util.concurrent.CompletableFuture) Graph(au.gov.asd.tac.constellation.graph.Graph) Tab(javafx.scene.control.Tab) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) CompletableFuture(java.util.concurrent.CompletableFuture) List(java.util.List) ObservableList(javafx.collections.ObservableList) ArrayList(java.util.ArrayList) Test(org.testng.annotations.Test)

Example 5 with WaitForQueriesToCompleteTask

use of au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask in project constellation by constellation-app.

the class ExecuteListenerNGTest method handle_results_dir_does_not_exist.

@Test
public void handle_results_dir_does_not_exist() {
    // Because the DataAccessPreferenceUtilities setter has null and non-dir
    // checks we have to manually add this into the preferences.
    final File tmpDir = new File("/SOMETHING_THAT_WOULD_NEVER_EXIST");
    Preferences prefs = NbPreferences.forModule(DataAccessPreferenceUtilities.class);
    prefs.put("saveDataDir", tmpDir.getAbsolutePath());
    // Set this preference to false so that plugins are not de-selected at the end
    DataAccessPreferenceUtilities.setDeselectPluginsOnExecute(false);
    // Set the current graph ID so the code doesn't try to create one
    DataAccessPaneState.setCurrentGraphId(GRAPH_ID);
    // Set up our fake tab pane
    final Tab tab1 = mock(Tab.class);
    when(tabPane.getTabs()).thenReturn(FXCollections.observableArrayList(tab1));
    final QueryPhasePane queryPhasePane1 = mock(QueryPhasePane.class);
    dataAccessTabPaneMockedStatic.when(() -> DataAccessTabPane.getQueryPhasePane(tab1)).thenReturn(queryPhasePane1);
    dataAccessTabPaneMockedStatic.when(() -> DataAccessTabPane.tabHasEnabledPlugins(tab1)).thenReturn(true);
    final DataSourceTitledPane dataSourceTitledPane1 = mock(DataSourceTitledPane.class);
    when(queryPhasePane1.getDataAccessPanes()).thenReturn(List.of(dataSourceTitledPane1));
    final ActionEvent event = mock(ActionEvent.class);
    try (MockedConstruction<WaitForQueriesToCompleteTask> waitForMockedConstruction = Mockito.mockConstruction(WaitForQueriesToCompleteTask.class, (waitForMock, cntxt) -> {
        assertEquals(cntxt.arguments(), List.of(dataAccessPane, GRAPH_ID));
    })) {
        executeListener.handle(event);
        // So the directory the results are meant to be written to doesn't exist,
        // verify that the notifier is displayed.
        verify(notificationDisplayer).notify("Save raw results", UserInterfaceIconProvider.ERROR.buildIcon(16, ConstellationColor.CHERRY.getJavaColor()), "Results directory /SOMETHING_THAT_WOULD_NEVER_EXIST does not exist", null);
        // No need to verify everything. Just make sure the main parts are still
        // executed to show that the plugins are still run after the error
        verify(pluginExecution).executeLater(null);
        verify(queryPhasePane1).runPlugins(null);
        completableFutureMockedStatic.verify(() -> CompletableFuture.runAsync(same(waitForMockedConstruction.constructed().get(0)), any(ExecutorService.class)));
        // Verify that the plugins are not de-selected
        verifyNoInteractions(dataSourceTitledPane1);
    }
}
Also used : DataSourceTitledPane(au.gov.asd.tac.constellation.views.dataaccess.panes.DataSourceTitledPane) WaitForQueriesToCompleteTask(au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask) Tab(javafx.scene.control.Tab) QueryPhasePane(au.gov.asd.tac.constellation.views.dataaccess.panes.QueryPhasePane) ActionEvent(javafx.event.ActionEvent) NbPreferences(org.openide.util.NbPreferences) Preferences(java.util.prefs.Preferences) File(java.io.File) Test(org.testng.annotations.Test)

Aggregations

WaitForQueriesToCompleteTask (au.gov.asd.tac.constellation.views.dataaccess.tasks.WaitForQueriesToCompleteTask)5 Tab (javafx.scene.control.Tab)5 CompletableFuture (java.util.concurrent.CompletableFuture)4 Future (java.util.concurrent.Future)4 QueryPhasePane (au.gov.asd.tac.constellation.views.dataaccess.panes.QueryPhasePane)3 File (java.io.File)3 Test (org.testng.annotations.Test)3 Graph (au.gov.asd.tac.constellation.graph.Graph)2 DataSourceTitledPane (au.gov.asd.tac.constellation.views.dataaccess.panes.DataSourceTitledPane)2 ActionEvent (javafx.event.ActionEvent)2 GraphManager (au.gov.asd.tac.constellation.graph.manager.GraphManager)1 NewDefaultSchemaGraphAction (au.gov.asd.tac.constellation.graph.node.create.NewDefaultSchemaGraphAction)1 PluginGraphs (au.gov.asd.tac.constellation.plugins.PluginGraphs)1 PluginInteraction (au.gov.asd.tac.constellation.plugins.PluginInteraction)1 PluginParameters (au.gov.asd.tac.constellation.plugins.parameters.PluginParameters)1 SimplePlugin (au.gov.asd.tac.constellation.plugins.templates.SimplePlugin)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 ExecutorService (java.util.concurrent.ExecutorService)1 Preferences (java.util.prefs.Preferences)1