This is an automated email from the ASF dual-hosted git repository.

mcgilman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/master by this push:
     new 5ca3655  NIFI-6381 - Make Parameters and Parameter Contexts searchable 
in UI
5ca3655 is described below

commit 5ca3655dbff449ad9536e143c27bf2218c43695a
Author: Rob Fellows <[email protected]>
AuthorDate: Thu Sep 12 14:26:16 2019 -0400

    NIFI-6381 - Make Parameters and Parameter Contexts searchable in UI
    
    NIFI-6381 - remove wildcard imports
    
    This closes #3728
---
 .../nifi/web/api/dto/search/SearchResultsDTO.java  |  29 ++++++
 .../nifi/web/controller/ControllerFacade.java      |   1 +
 .../web/controller/ControllerSearchService.java    |  73 +++++++++++++++
 .../controller/ControllerSearchServiceTest.java    |  97 +++++++++++++++++++
 .../nf-ng-canvas-flow-status-controller.js         | 104 +++++++++++++++------
 .../webapp/js/nf/canvas/nf-parameter-contexts.js   |  25 ++++-
 6 files changed, 297 insertions(+), 32 deletions(-)

diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/search/SearchResultsDTO.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/search/SearchResultsDTO.java
index acad58b..5054c29 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/search/SearchResultsDTO.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/search/SearchResultsDTO.java
@@ -35,6 +35,8 @@ public class SearchResultsDTO {
     private List<ComponentSearchResultDTO> outputPortResults = new 
ArrayList<>();
     private List<ComponentSearchResultDTO> remoteProcessGroupResults = new 
ArrayList<>();
     private List<ComponentSearchResultDTO> funnelResults = new ArrayList<>();
+    private List<ComponentSearchResultDTO> parameterContextResults = new 
ArrayList<>();
+    private List<ComponentSearchResultDTO> parameterResults = new 
ArrayList<>();
 
     /**
      * @return The processors that matched the search
@@ -134,4 +136,31 @@ public class SearchResultsDTO {
         this.funnelResults = funnelResults;
     }
 
+    /**
+     * @return parameter contexts that matched the search.
+     */
+    @ApiModelProperty(
+        value = "The parameter contexts that matched the search."
+    )
+    public List<ComponentSearchResultDTO> getParameterContextResults() {
+        return parameterContextResults;
+    }
+
+    public void setParameterContextResults(List<ComponentSearchResultDTO> 
parameterContextResults) {
+        this.parameterContextResults = parameterContextResults;
+    }
+
+    /**
+     * @return parameters that matched the search.
+     */
+    @ApiModelProperty(
+            value = "The parameters that matched the search."
+    )
+    public List<ComponentSearchResultDTO> getParameterResults() {
+        return parameterResults;
+    }
+
+    public void setParameterResults(List<ComponentSearchResultDTO> 
parameterResults) {
+        this.parameterResults = parameterResults;
+    }
 }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index b886d94..ec7f206 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -1619,6 +1619,7 @@ public class ControllerFacade implements Authorizable {
         final SearchResultsDTO results = new SearchResultsDTO();
 
         controllerSearchService.search(results, search, rootGroup);
+        controllerSearchService.searchParameters(results, search);
 
         return results;
     }
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerSearchService.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerSearchService.java
index c08d210..9bec4bb 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerSearchService.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerSearchService.java
@@ -36,6 +36,9 @@ import org.apache.nifi.flowfile.FlowFilePrioritizer;
 import org.apache.nifi.groups.ProcessGroup;
 import org.apache.nifi.groups.RemoteProcessGroup;
 import org.apache.nifi.nar.NarCloseable;
+import org.apache.nifi.parameter.Parameter;
+import org.apache.nifi.parameter.ParameterContext;
+import org.apache.nifi.parameter.ParameterContextManager;
 import org.apache.nifi.processor.DataUnit;
 import org.apache.nifi.processor.Processor;
 import org.apache.nifi.processor.Relationship;
@@ -56,6 +59,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -163,6 +167,39 @@ public class ControllerSearchService {
         }
     }
 
+    /**
+     * Searches all parameter contexts and parameters
+     * @param results Search results
+     * @param search  The search term
+     */
+    public void searchParameters(final SearchResultsDTO results, final String 
search) {
+        final NiFiUser user = NiFiUserUtils.getNiFiUser();
+        ParameterContextManager parameterContextManager = 
flowController.getFlowManager().getParameterContextManager();
+
+        final Set<ParameterContext> parameterContexts = 
parameterContextManager.getParameterContexts();
+        for (final ParameterContext parameterContext : parameterContexts) {
+            if (parameterContext.isAuthorized(authorizer, RequestAction.READ, 
user)) {
+                ComponentSearchResultDTO parameterContextMatch = 
search(search, parameterContext);
+                if (parameterContextMatch != null) {
+                    
results.getParameterContextResults().add(parameterContextMatch);
+                }
+
+                // search each parameter within the context as well
+                for (Parameter parameter : 
parameterContext.getParameters().values()) {
+                    ComponentSearchResultDTO parameterMatch = search(search, 
parameter);
+                    if (parameterMatch != null) {
+                        final SearchResultGroupDTO paramContextGroup = new 
SearchResultGroupDTO();
+                        
paramContextGroup.setId(parameterContext.getIdentifier());
+                        paramContextGroup.setName(parameterContext.getName());
+                        parameterMatch.setParentGroup(paramContextGroup);
+
+                        results.getParameterResults().add(parameterMatch);
+                    }
+                }
+            }
+        }
+    }
+
     private ComponentSearchResultDTO search(final String searchStr, final Port 
port) {
         final List<String> matches = new ArrayList<>();
 
@@ -474,6 +511,42 @@ public class ControllerSearchService {
         return dto;
     }
 
+    private ComponentSearchResultDTO search(final String searchString, final 
ParameterContext parameterContext) {
+        final List<String> matches = new ArrayList<>();
+        addIfAppropriate(searchString, parameterContext.getIdentifier(), "Id", 
matches);
+        addIfAppropriate(searchString, parameterContext.getName(), "Name", 
matches);
+        addIfAppropriate(searchString, parameterContext.getDescription(), 
"Description", matches);
+
+        if (matches.isEmpty()) {
+            return null;
+        }
+
+        final ComponentSearchResultDTO dto = new ComponentSearchResultDTO();
+        dto.setId(parameterContext.getIdentifier());
+        dto.setName(parameterContext.getName());
+        dto.setMatches(matches);
+        return dto;
+    }
+
+    private ComponentSearchResultDTO search(final String searchString, final 
Parameter parameter) {
+        final List<String> matches = new ArrayList<>();
+        addIfAppropriate(searchString, parameter.getDescriptor().getName(), 
"Name", matches);
+        addIfAppropriate(searchString, 
parameter.getDescriptor().getDescription(), "Description", matches);
+        if (!parameter.getDescriptor().isSensitive()) {
+            addIfAppropriate(searchString, parameter.getValue(), "Value", 
matches);
+        }
+
+        if (matches.isEmpty()) {
+            return null;
+        }
+
+        final ComponentSearchResultDTO dto = new ComponentSearchResultDTO();
+        dto.setId(parameter.getDescriptor().getName());
+        dto.setName(parameter.getDescriptor().getName());
+        dto.setMatches(matches);
+        return dto;
+    }
+
     /**
      * Builds the nearest versioned parent result group for a given user.
      *
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerSearchServiceTest.java
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerSearchServiceTest.java
index 68749a3..092cb10 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerSearchServiceTest.java
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/controller/ControllerSearchServiceTest.java
@@ -19,9 +19,15 @@ package org.apache.nifi.web.controller;
 import org.apache.nifi.authorization.Authorizer;
 import org.apache.nifi.authorization.RequestAction;
 import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.controller.FlowController;
 import org.apache.nifi.controller.ProcessorNode;
 import org.apache.nifi.controller.StandardProcessorNode;
+import org.apache.nifi.controller.flow.FlowManager;
 import org.apache.nifi.groups.ProcessGroup;
+import org.apache.nifi.parameter.Parameter;
+import org.apache.nifi.parameter.ParameterContext;
+import org.apache.nifi.parameter.ParameterContextManager;
+import org.apache.nifi.parameter.ParameterDescriptor;
 import org.apache.nifi.processor.Processor;
 import org.apache.nifi.registry.VariableRegistry;
 import org.apache.nifi.registry.flow.StandardVersionControlInformation;
@@ -33,25 +39,39 @@ import org.junit.Test;
 import org.mockito.AdditionalMatchers;
 import org.mockito.Mockito;
 
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
 public class ControllerSearchServiceTest {
     private MutableVariableRegistry variableRegistry;
     private ControllerSearchService service;
     private SearchResultsDTO searchResultsDTO;
+    private FlowController flowController;
+    private ParameterContextManager parameterContextManager;
 
     @Before
     public void setUp() {
         variableRegistry = mock(MutableVariableRegistry.class);
         service = new ControllerSearchService();
         searchResultsDTO = new SearchResultsDTO();
+        flowController = mock(FlowController.class);
+
+        FlowManager mockFlowManager = mock(FlowManager.class);
+        parameterContextManager = mock(ParameterContextManager.class);
+
+        doReturn(mockFlowManager).when(flowController).getFlowManager();
+        
doReturn(parameterContextManager).when(mockFlowManager).getParameterContextManager();
+        service.setFlowController(flowController);
     }
 
     @Test
@@ -339,6 +359,83 @@ public class ControllerSearchServiceTest {
         
assertTrue(searchResultsDTO.getProcessorResults().get(0).getVersionedGroup().getName()
 == null);
     }
 
+    @Test
+    public void testSearchParameterContext() {
+        final ParameterContext paramContext1 = 
setupMockedParameterContext("foo", "description for parameter context foo", 1, 
"foo_param", true);
+        final ParameterContext paramContext2 = 
setupMockedParameterContext("bar", "description for parameter context bar", 2, 
"bar_param", true);
+        final Set<ParameterContext> mockedParameterContexts = new 
HashSet<ParameterContext>();
+        mockedParameterContexts.add(paramContext1);
+        mockedParameterContexts.add(paramContext2);
+
+        
Mockito.doReturn(mockedParameterContexts).when(parameterContextManager).getParameterContexts();
+
+        service.searchParameters(searchResultsDTO, "foo");
+
+        assertTrue(searchResultsDTO.getParameterContextResults().size() == 1);
+        
assertTrue(searchResultsDTO.getParameterContextResults().get(0).getId().equals("fooId"));
+        
assertTrue(searchResultsDTO.getParameterContextResults().get(0).getName().equals("foo"));
+        // should have a match for the name, id, description
+        
assertTrue(searchResultsDTO.getParameterContextResults().get(0).getMatches().size()
 == 3);
+
+        assertTrue(searchResultsDTO.getParameterResults().size() == 1);
+
+        
assertTrue(searchResultsDTO.getParameterResults().get(0).getParentGroup().getId().equals("fooId"));
+        
assertTrue(searchResultsDTO.getParameterResults().get(0).getName().equals("foo_param_0"));
+        // and the parameter name, parameter description, and the parameter 
value
+        
assertTrue(searchResultsDTO.getParameterResults().get(0).getMatches().size() == 
3);
+    }
+
+    @Test
+    public void testSearchParameterContextNotAuthorized() {
+        final ParameterContext paramContext1 = 
setupMockedParameterContext("foo", "description for parameter context foo", 1, 
"foo_param", false);
+        final ParameterContext paramContext2 = 
setupMockedParameterContext("bar", "description for parameter context bar", 2, 
"bar_param", true);
+        final Set<ParameterContext> mockedParameterContexts = new 
HashSet<ParameterContext>();
+        mockedParameterContexts.add(paramContext1);
+        mockedParameterContexts.add(paramContext2);
+
+        
Mockito.doReturn(mockedParameterContexts).when(parameterContextManager).getParameterContexts();
+
+        service.searchParameters(searchResultsDTO, "foo");
+
+        // the matching parameter context is not readable by the user, so 
there should not be any results
+        assertTrue(searchResultsDTO.getParameterContextResults().size() == 0);
+        assertTrue(searchResultsDTO.getParameterResults().size() == 0);
+    }
+
+    /**
+     * Sets up a mock Parameter Context including isAuthorized()
+     * @param name                     name of the parameter context
+     * @param description              description of the parameter context
+     * @param numberOfParams           number of parameters to include as part 
of this context
+     * @param parameterNamePrefix      a prefix for the parameter names
+     * @param authorizedToRead         whether or not the user can read the 
parameter context
+     * @return ParameterContext
+     */
+    private ParameterContext setupMockedParameterContext(String name, String 
description, int numberOfParams, String parameterNamePrefix, boolean 
authorizedToRead) {
+        final ParameterContext parameterContext = mock(ParameterContext.class);
+        Mockito.doReturn(name + "Id").when(parameterContext).getIdentifier();
+        Mockito.doReturn(name).when(parameterContext).getName();
+        Mockito.doReturn(description).when(parameterContext).getDescription();
+        
Mockito.doReturn(authorizedToRead).when(parameterContext).isAuthorized(any(Authorizer.class),
 eq(RequestAction.READ), any(NiFiUser.class));
+        
Mockito.doReturn(authorizedToRead).when(parameterContext).isAuthorized(eq(null),
 eq(RequestAction.READ), eq(null));
+
+        Map<ParameterDescriptor, Parameter> parameters = new HashMap<>();
+        for (int i = 0; i < numberOfParams; i++) {
+            final ParameterDescriptor descriptor = new 
ParameterDescriptor.Builder()
+                    .name(parameterNamePrefix + "_" + i)
+                    .description("Description for " + parameterNamePrefix + 
"_" + i)
+                    .sensitive(false)
+                    .build();
+
+            final Parameter param = new Parameter(descriptor, 
parameterNamePrefix + "_" + i + " value");
+            parameters.put(descriptor, param);
+        }
+
+        Mockito.doReturn(parameters).when(parameterContext).getParameters();
+
+        return parameterContext;
+    }
+
     /**
      * Mocks Processor including isAuthorized() and its name & id.
      *
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js
index e6558f5..0722295 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-flow-status-controller.js
@@ -26,9 +26,10 @@
                 'nf.ContextMenu',
                 'nf.ClusterSummary',
                 'nf.ErrorHandler',
-                'nf.Settings'],
-            function ($, nfCommon, nfDialog, nfCanvasUtils, nfContextMenu, 
nfClusterSummary, nfErrorHandler, nfSettings) {
-                return (nf.ng.Canvas.FlowStatusCtrl = factory($, nfCommon, 
nfDialog, nfCanvasUtils, nfContextMenu, nfClusterSummary, nfErrorHandler, 
nfSettings));
+                'nf.Settings',
+                'nf.ParameterContexts'],
+            function ($, nfCommon, nfDialog, nfCanvasUtils, nfContextMenu, 
nfClusterSummary, nfErrorHandler, nfSettings, nfParameterContexts) {
+                return (nf.ng.Canvas.FlowStatusCtrl = factory($, nfCommon, 
nfDialog, nfCanvasUtils, nfContextMenu, nfClusterSummary, nfErrorHandler, 
nfSettings, nfParameterContexts));
             });
     } else if (typeof exports === 'object' && typeof module === 'object') {
         module.exports = (nf.ng.Canvas.FlowStatusCtrl =
@@ -39,7 +40,8 @@
                 require('nf.ContextMenu'),
                 require('nf.ClusterSummary'),
                 require('nf.ErrorHandler'),
-                require('nf.Settings')));
+                require('nf.Settings'),
+                require('nf.ParameterContexts')));
     } else {
         nf.ng.Canvas.FlowStatusCtrl = factory(root.$,
             root.nf.Common,
@@ -48,9 +50,10 @@
             root.nf.ContextMenu,
             root.nf.ClusterSummary,
             root.nf.ErrorHandler,
-            root.nf.Settings);
+            root.nf.Settings,
+            root.nf.ParameterContexts);
     }
-}(this, function ($, nfCommon, nfDialog, nfCanvasUtils, nfContextMenu, 
nfClusterSummary, nfErrorHandler, nfSettings) {
+}(this, function ($, nfCommon, nfDialog, nfCanvasUtils, nfContextMenu, 
nfClusterSummary, nfErrorHandler, nfSettings, nfParameterContexts) {
     'use strict';
 
     return function (serviceProvider) {
@@ -145,7 +148,7 @@
                             if 
(!nfCommon.isEmpty(searchResults.processorResults)) {
                                 ul.append('<li class="search-header"><div 
class="search-result-icon icon icon-processor"></div>Processors</li>');
                                 $.each(searchResults.processorResults, 
function (i, processorMatch) {
-                                    nfSearchAutocomplete._renderItem(ul, 
processorMatch);
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, processorMatch, { type: 'processor' }));
                                 });
                             }
 
@@ -153,7 +156,7 @@
                             if 
(!nfCommon.isEmpty(searchResults.processGroupResults)) {
                                 ul.append('<li class="search-header"><div 
class="search-result-icon icon icon-group"></div>Process Groups</li>');
                                 $.each(searchResults.processGroupResults, 
function (i, processGroupMatch) {
-                                    nfSearchAutocomplete._renderItem(ul, 
processGroupMatch);
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, processGroupMatch, { type: 'process group' }));
                                 });
                             }
 
@@ -161,7 +164,7 @@
                             if 
(!nfCommon.isEmpty(searchResults.remoteProcessGroupResults)) {
                                 ul.append('<li class="search-header"><div 
class="search-result-icon icon icon-group-remote"></div>Remote Process 
Groups</li>');
                                 
$.each(searchResults.remoteProcessGroupResults, function (i, 
remoteProcessGroupMatch) {
-                                    nfSearchAutocomplete._renderItem(ul, 
remoteProcessGroupMatch);
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, remoteProcessGroupMatch, { type: 'remote process group' }));
                                 });
                             }
 
@@ -169,7 +172,7 @@
                             if 
(!nfCommon.isEmpty(searchResults.connectionResults)) {
                                 ul.append('<li class="search-header"><div 
class="search-result-icon icon icon-connect"></div>Connections</li>');
                                 $.each(searchResults.connectionResults, 
function (i, connectionMatch) {
-                                    nfSearchAutocomplete._renderItem(ul, 
connectionMatch);
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, connectionMatch, { type: 'connection' }));
                                 });
                             }
 
@@ -177,7 +180,7 @@
                             if 
(!nfCommon.isEmpty(searchResults.inputPortResults)) {
                                 ul.append('<li class="search-header"><div 
class="search-result-icon icon icon-port-in"></div>Input Ports</li>');
                                 $.each(searchResults.inputPortResults, 
function (i, inputPortMatch) {
-                                    nfSearchAutocomplete._renderItem(ul, 
inputPortMatch);
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, inputPortMatch, { type: 'input port' }));
                                 });
                             }
 
@@ -185,7 +188,7 @@
                             if 
(!nfCommon.isEmpty(searchResults.outputPortResults)) {
                                 ul.append('<li class="search-header"><div 
class="search-result-icon icon icon-port-out"></div>Output Ports</li>');
                                 $.each(searchResults.outputPortResults, 
function (i, outputPortMatch) {
-                                    nfSearchAutocomplete._renderItem(ul, 
outputPortMatch);
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, outputPortMatch, { type: 'output port' }));
                                 });
                             }
 
@@ -193,7 +196,23 @@
                             if 
(!nfCommon.isEmpty(searchResults.funnelResults)) {
                                 ul.append('<li class="search-header"><div 
class="search-result-icon icon icon-funnel"></div>Funnels</li>');
                                 $.each(searchResults.funnelResults, function 
(i, funnelMatch) {
-                                    nfSearchAutocomplete._renderItem(ul, 
funnelMatch);
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, funnelMatch, { type: 'funnel' }));
+                                });
+                            }
+
+                            // show all parameter contexts and parameters
+                            if 
(!nfCommon.isEmpty(searchResults.parameterContextResults)) {
+                                ul.append('<li class="search-header"><div 
class="search-result-icon icon"></div>Parameter Contexts</li>');
+                                $.each(searchResults.parameterContextResults, 
function (i, parameterContextMatch) {
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, parameterContextMatch, { type: 'parameter context' }));
+                                });
+                            }
+
+                            // show all parameters
+                            if 
(!nfCommon.isEmpty(searchResults.parameterResults)) {
+                                ul.append('<li class="search-header"><div 
class="search-result-icon icon"></div>Parameters</li>');
+                                $.each(searchResults.parameterResults, 
function (i, parameterMatch) {
+                                    nfSearchAutocomplete._renderItem(ul, 
$.extend({}, parameterMatch, { type: 'parameter' }));
                                 });
                             }
 
@@ -204,21 +223,36 @@
                         },
                         _renderItem: function (ul, match) {
                             var itemHeader = $('<div 
class="search-match-header"></div>').text(match.name);
-
-                            var parentGroupHeader = $('<div 
class="search-match-header"></div>').append(document.createTextNode('Parent: 
'));
-                            var parentGroup = match.parentGroup.name ? 
match.parentGroup.name : match.parentGroup.id;
-                            parentGroupHeader = 
parentGroupHeader.append($('<span></span>').text(parentGroup));
-
-                            var versionedGroupHeader = $('<div 
class="search-match-header"></div>').append(document.createTextNode('Versioned: 
'));
-                            var versionedGroup = '-';
-
-                            if 
(nfCommon.isDefinedAndNotNull(match.versionedGroup)) {
-                                versionedGroup = match.versionedGroup.name ? 
match.versionedGroup.name : match.versionedGroup.id;
+                            var itemContent = $('<a></a>').append(itemHeader);
+
+                            if (match.type !== 'parameter context' && 
match.type !== 'parameter') {
+                                var parentGroupHeader = $('<div 
class="search-match-header"></div>').append(document.createTextNode('Parent: 
'));
+                                var parentGroup = '-';
+                                if 
(nfCommon.isDefinedAndNotNull(match.parentGroup)) {
+                                    parentGroup = match.parentGroup.name ? 
match.parentGroup.name : match.parentGroup.id;
+                                }
+                                parentGroupHeader = 
parentGroupHeader.append($('<span></span>').text(parentGroup));
+
+                                var versionedGroupHeader = $('<div 
class="search-match-header"></div>').append(document.createTextNode('Versioned: 
'));
+                                var versionedGroup = '-';
+
+                                if 
(nfCommon.isDefinedAndNotNull(match.versionedGroup)) {
+                                    versionedGroup = match.versionedGroup.name 
? match.versionedGroup.name : match.versionedGroup.id;
+                                }
+
+                                versionedGroupHeader = 
versionedGroupHeader.append($('<span></span>').text(versionedGroup));
+                                // create a search item wrapper
+                                
itemContent.append(parentGroupHeader).append(versionedGroupHeader);
+                            } else if (match.type === 'parameter') {
+                                var paramContextHeader = $('<div 
class="search-match-header"></div>').append(document.createTextNode('Parameter 
Context: '));
+                                var paramContext = '-';
+                                if 
(nfCommon.isDefinedAndNotNull(match.parentGroup)) {
+                                    paramContext = match.parentGroup.name ? 
match.parentGroup.name : match.parentGroup.id;
+                                }
+                                paramContextHeader = 
paramContextHeader.append($('<span></span>').text(paramContext));
+                                itemContent.append(paramContextHeader);
                             }
 
-                            versionedGroupHeader = 
versionedGroupHeader.append($('<span></span>').text(versionedGroup));
-                            // create a search item wrapper
-                            var itemContent = 
$('<a></a>').append(itemHeader).append(parentGroupHeader).append(versionedGroupHeader);
                             // append all matches
                             $.each(match.matches, function (i, match) {
                                 itemContent.append($('<div 
class="search-match"></div>').text(match));
@@ -251,10 +285,22 @@
                         },
                         select: function (event, ui) {
                             var item = ui.item;
-                            var group = item.parentGroup;
 
-                            // show the selected component
-                            nfCanvasUtils.showComponent(group.id, item.id);
+                            switch (item.type) {
+                                case 'parameter context':
+                                    
nfParameterContexts.showParameterContexts(item.id);
+                                    break;
+                                case 'parameter':
+                                    var paramContext = item.parentGroup;
+                                    
nfParameterContexts.showParameterContext(paramContext.id, null, item.name);
+                                    break;
+                                default:
+                                    var group = item.parentGroup;
+
+                                    // show the selected component
+                                    nfCanvasUtils.showComponent(group.id, 
item.id);
+                                    break;
+                            }
 
                             searchCtrl.getInputElement().val('').blur();
 
diff --git 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js
 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js
index f6724fd..776616e 100644
--- 
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js
+++ 
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-parameter-contexts.js
@@ -1995,8 +1995,10 @@
 
     /**
      * Loads the parameter contexts.
+     *
+     * @param parameterContextToSelect   id of the parameter context to select 
in the grid
      */
-    var loadParameterContexts = function () {
+    var loadParameterContexts = function (parameterContextToSelect) {
         var parameterContexts = $.Deferred(function (deferred) {
             $.ajax({
                 type: 'GET',
@@ -2026,6 +2028,21 @@
             parameterContextsData.setItems(contexts);
             parameterContextsData.reSort();
             parameterContextsGrid.invalidate();
+
+            // if we are pre-selecting a specific parameter context, get the 
row to select
+            if (nfCommon.isDefinedAndNotNull(parameterContextToSelect)) {
+                var parameterContextRow = null;
+                $.each(contexts, function (i, contextEntity) {
+                    if (contextEntity.id === parameterContextToSelect) {
+                        parameterContextRow = 
parameterContextsData.getRowById(parameterContextToSelect);
+                        return false;
+                    }
+                });
+                if (parameterContextRow !== null) {
+                    // select the desired row
+                    
parameterContextsGrid.setSelectedRows([parameterContextRow]);
+                }
+            }
         }).fail(nfErrorHandler.handleAjaxError);
     };
 
@@ -2360,13 +2377,15 @@
 
         /**
          * Shows the parameter context dialog.
+         *
+         * @param id         The parameter context id to select
          */
-        showParameterContexts: function () {
+        showParameterContexts: function (id) {
             // conditionally allow creation of new parameter contexts
             $('#new-parameter-context').prop('disabled', 
!nfCommon.canModifyParameterContexts());
 
             // load the parameter contexts
-            return loadParameterContexts().done(showParameterContexts);
+            return loadParameterContexts(id).done(showParameterContexts);
         },
 
         /**

Reply via email to