mirror of https://github.com/apache/nifi.git
NIFI-5925: Added controller services to set of components that are searched
NIFI-5925: cleanup, add negative test NIFI-5925: fixed checkstyle This closes #4105 Signed-off-by: Mike Thomsen <mthomsen@apache.org>
This commit is contained in:
parent
5fd25d6235
commit
aeaf953e06
|
@ -36,6 +36,7 @@ public class SearchResultsDTO {
|
||||||
private List<ComponentSearchResultDTO> remoteProcessGroupResults = new ArrayList<>();
|
private List<ComponentSearchResultDTO> remoteProcessGroupResults = new ArrayList<>();
|
||||||
private List<ComponentSearchResultDTO> funnelResults = new ArrayList<>();
|
private List<ComponentSearchResultDTO> funnelResults = new ArrayList<>();
|
||||||
private List<ComponentSearchResultDTO> labelResults = new ArrayList<>();
|
private List<ComponentSearchResultDTO> labelResults = new ArrayList<>();
|
||||||
|
private List<ComponentSearchResultDTO> controllerServiceNodeResults = new ArrayList<>();
|
||||||
private List<ComponentSearchResultDTO> parameterContextResults = new ArrayList<>();
|
private List<ComponentSearchResultDTO> parameterContextResults = new ArrayList<>();
|
||||||
private List<ComponentSearchResultDTO> parameterResults = new ArrayList<>();
|
private List<ComponentSearchResultDTO> parameterResults = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -151,6 +152,20 @@ public class SearchResultsDTO {
|
||||||
this.labelResults = labelResults;
|
this.labelResults = labelResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the controller service nodes that matched the search
|
||||||
|
*/
|
||||||
|
@ApiModelProperty(
|
||||||
|
value = "The controller service nodes that matched the search"
|
||||||
|
)
|
||||||
|
public List<ComponentSearchResultDTO> getControllerServiceNodeResults() {
|
||||||
|
return controllerServiceNodeResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setControllerServiceNodeResults(List<ComponentSearchResultDTO> controllerServiceNodeResults) {
|
||||||
|
this.controllerServiceNodeResults = controllerServiceNodeResults;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return parameter contexts that matched the search.
|
* @return parameter contexts that matched the search.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.nifi.controller.ProcessorNode;
|
||||||
import org.apache.nifi.controller.ScheduledState;
|
import org.apache.nifi.controller.ScheduledState;
|
||||||
import org.apache.nifi.controller.label.Label;
|
import org.apache.nifi.controller.label.Label;
|
||||||
import org.apache.nifi.controller.queue.FlowFileQueue;
|
import org.apache.nifi.controller.queue.FlowFileQueue;
|
||||||
|
import org.apache.nifi.controller.service.ControllerServiceNode;
|
||||||
import org.apache.nifi.flowfile.FlowFilePrioritizer;
|
import org.apache.nifi.flowfile.FlowFilePrioritizer;
|
||||||
import org.apache.nifi.groups.ProcessGroup;
|
import org.apache.nifi.groups.ProcessGroup;
|
||||||
import org.apache.nifi.groups.RemoteProcessGroup;
|
import org.apache.nifi.groups.RemoteProcessGroup;
|
||||||
|
@ -175,13 +176,67 @@ public class ControllerSearchService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (final ControllerServiceNode controllerServiceNode : group.getControllerServices(false)) {
|
||||||
|
if (controllerServiceNode.isAuthorized(authorizer, RequestAction.READ, user)) {
|
||||||
|
final ComponentSearchResultDTO match = search(search, controllerServiceNode);
|
||||||
|
if (match != null) {
|
||||||
|
match.setGroupId(group.getIdentifier());
|
||||||
|
match.setParentGroup(buildResultGroup(group, user));
|
||||||
|
match.setVersionedGroup(buildVersionedGroup(group, user));
|
||||||
|
results.getControllerServiceNodeResults().add(match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (final ProcessGroup processGroup : group.getProcessGroups()) {
|
for (final ProcessGroup processGroup : group.getProcessGroups()) {
|
||||||
search(results, search, processGroup);
|
search(results, search, processGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches controller service for the given search term
|
||||||
|
*
|
||||||
|
* @param search the search term
|
||||||
|
* @param controllerServiceNode a group controller service node
|
||||||
|
*/
|
||||||
|
private ComponentSearchResultDTO search(final String search, final ControllerServiceNode controllerServiceNode) {
|
||||||
|
final List<String> matches = new ArrayList<>();
|
||||||
|
addIfAppropriate(search, controllerServiceNode.getIdentifier(), "Id", matches);
|
||||||
|
addIfAppropriate(search, controllerServiceNode.getVersionedComponentId().orElse(null), "Version Control ID", matches);
|
||||||
|
addIfAppropriate(search, controllerServiceNode.getName(), "Name", matches);
|
||||||
|
addIfAppropriate(search, controllerServiceNode.getComments(), "Comments", matches);
|
||||||
|
|
||||||
|
// search property values
|
||||||
|
controllerServiceNode.getRawPropertyValues().forEach((property, propertyValue) -> {
|
||||||
|
addIfAppropriate(search, property.getName(), "Property Name", matches);
|
||||||
|
addIfAppropriate(search, property.getDescription(), "Property Description", matches);
|
||||||
|
|
||||||
|
// never include sensitive properties in search results
|
||||||
|
if (property.isSensitive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propertyValue != null) {
|
||||||
|
addIfAppropriate(search, propertyValue, "Property Value", matches);
|
||||||
|
} else {
|
||||||
|
addIfAppropriate(search, property.getDefaultValue(), "Property Value", matches);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matches.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ComponentSearchResultDTO dto = new ComponentSearchResultDTO();
|
||||||
|
dto.setId(controllerServiceNode.getIdentifier());
|
||||||
|
dto.setName(controllerServiceNode.getName());
|
||||||
|
dto.setMatches(matches);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches all parameter contexts and parameters
|
* Searches all parameter contexts and parameters
|
||||||
|
*
|
||||||
* @param results Search results
|
* @param results Search results
|
||||||
* @param search The search term
|
* @param search The search term
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,11 +19,15 @@ package org.apache.nifi.web.controller;
|
||||||
import org.apache.nifi.authorization.Authorizer;
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
import org.apache.nifi.authorization.RequestAction;
|
import org.apache.nifi.authorization.RequestAction;
|
||||||
import org.apache.nifi.authorization.user.NiFiUser;
|
import org.apache.nifi.authorization.user.NiFiUser;
|
||||||
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
import org.apache.nifi.controller.ControllerService;
|
||||||
import org.apache.nifi.controller.FlowController;
|
import org.apache.nifi.controller.FlowController;
|
||||||
import org.apache.nifi.controller.ProcessorNode;
|
import org.apache.nifi.controller.ProcessorNode;
|
||||||
import org.apache.nifi.controller.StandardProcessorNode;
|
import org.apache.nifi.controller.StandardProcessorNode;
|
||||||
import org.apache.nifi.controller.flow.FlowManager;
|
import org.apache.nifi.controller.flow.FlowManager;
|
||||||
import org.apache.nifi.controller.label.Label;
|
import org.apache.nifi.controller.label.Label;
|
||||||
|
import org.apache.nifi.controller.service.ControllerServiceNode;
|
||||||
|
import org.apache.nifi.controller.service.StandardControllerServiceNode;
|
||||||
import org.apache.nifi.groups.ProcessGroup;
|
import org.apache.nifi.groups.ProcessGroup;
|
||||||
import org.apache.nifi.parameter.Parameter;
|
import org.apache.nifi.parameter.Parameter;
|
||||||
import org.apache.nifi.parameter.ParameterContext;
|
import org.apache.nifi.parameter.ParameterContext;
|
||||||
|
@ -50,6 +54,7 @@ import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.isNull;
|
import static org.mockito.ArgumentMatchers.isNull;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
@ -420,6 +425,86 @@ public class ControllerSearchServiceTest {
|
||||||
assertTrue(searchResultsDTO.getLabelResults().get(0).getName().equals("Value for label foo"));
|
assertTrue(searchResultsDTO.getLabelResults().get(0).getName().equals("Value for label foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchControllerServices() {
|
||||||
|
final ProcessGroup rootProcessGroup = setupMockedProcessGroup("root", null, true, variableRegistry, null);
|
||||||
|
|
||||||
|
final String controllerServiceName = "controllerServiceName";
|
||||||
|
final String controllerServiceId = controllerServiceName + "Id";
|
||||||
|
|
||||||
|
final Map<PropertyDescriptor, String> props = new HashMap<>();
|
||||||
|
final PropertyDescriptor prop1 = new PropertyDescriptor.Builder()
|
||||||
|
.name("prop1-name")
|
||||||
|
.displayName("prop1-displayname")
|
||||||
|
.description("prop1 description")
|
||||||
|
.defaultValue("prop1-default")
|
||||||
|
.build();
|
||||||
|
final PropertyDescriptor prop2 = new PropertyDescriptor.Builder()
|
||||||
|
.name("prop2-name")
|
||||||
|
.displayName("prop2-displayname")
|
||||||
|
.description("prop2 description")
|
||||||
|
.defaultValue("prop2-default")
|
||||||
|
.build();
|
||||||
|
props.put(prop1, "prop1-value");
|
||||||
|
props.put(prop2, null);
|
||||||
|
|
||||||
|
setupMockedControllerService(controllerServiceName, rootProcessGroup, true, props);
|
||||||
|
|
||||||
|
// search for name
|
||||||
|
service.search(searchResultsDTO, "controllerserv", rootProcessGroup);
|
||||||
|
|
||||||
|
assertEquals(1, searchResultsDTO.getControllerServiceNodeResults().size());
|
||||||
|
assertEquals(controllerServiceId, searchResultsDTO.getControllerServiceNodeResults().get(0).getId());
|
||||||
|
assertEquals(controllerServiceName, searchResultsDTO.getControllerServiceNodeResults().get(0).getName());
|
||||||
|
|
||||||
|
// search for comments
|
||||||
|
searchResultsDTO = new SearchResultsDTO();
|
||||||
|
service.search(searchResultsDTO, "foo comment", rootProcessGroup);
|
||||||
|
|
||||||
|
assertEquals(1, searchResultsDTO.getControllerServiceNodeResults().size());
|
||||||
|
assertEquals(controllerServiceId, searchResultsDTO.getControllerServiceNodeResults().get(0).getId());
|
||||||
|
assertEquals(controllerServiceName, searchResultsDTO.getControllerServiceNodeResults().get(0).getName());
|
||||||
|
|
||||||
|
// search for properties
|
||||||
|
searchResultsDTO = new SearchResultsDTO();
|
||||||
|
service.search(searchResultsDTO, "prop1-name", rootProcessGroup);
|
||||||
|
|
||||||
|
assertEquals(1, searchResultsDTO.getControllerServiceNodeResults().size());
|
||||||
|
assertEquals(controllerServiceId, searchResultsDTO.getControllerServiceNodeResults().get(0).getId());
|
||||||
|
assertEquals(controllerServiceName, searchResultsDTO.getControllerServiceNodeResults().get(0).getName());
|
||||||
|
|
||||||
|
// by default
|
||||||
|
searchResultsDTO = new SearchResultsDTO();
|
||||||
|
service.search(searchResultsDTO, "prop2-def", rootProcessGroup);
|
||||||
|
|
||||||
|
assertEquals(1, searchResultsDTO.getControllerServiceNodeResults().size());
|
||||||
|
assertEquals(controllerServiceId, searchResultsDTO.getControllerServiceNodeResults().get(0).getId());
|
||||||
|
assertEquals(controllerServiceName, searchResultsDTO.getControllerServiceNodeResults().get(0).getName());
|
||||||
|
|
||||||
|
// by description
|
||||||
|
searchResultsDTO = new SearchResultsDTO();
|
||||||
|
service.search(searchResultsDTO, "desc", rootProcessGroup);
|
||||||
|
|
||||||
|
// "desc" would typically match both props, but it's for the same controller service.
|
||||||
|
assertEquals(1, searchResultsDTO.getControllerServiceNodeResults().size());
|
||||||
|
assertEquals(controllerServiceId, searchResultsDTO.getControllerServiceNodeResults().get(0).getId());
|
||||||
|
assertEquals(controllerServiceName, searchResultsDTO.getControllerServiceNodeResults().get(0).getName());
|
||||||
|
|
||||||
|
// by specified value
|
||||||
|
searchResultsDTO = new SearchResultsDTO();
|
||||||
|
service.search(searchResultsDTO, "prop1-value", rootProcessGroup);
|
||||||
|
|
||||||
|
assertEquals(1, searchResultsDTO.getControllerServiceNodeResults().size());
|
||||||
|
assertEquals(controllerServiceId, searchResultsDTO.getControllerServiceNodeResults().get(0).getId());
|
||||||
|
assertEquals(controllerServiceName, searchResultsDTO.getControllerServiceNodeResults().get(0).getName());
|
||||||
|
|
||||||
|
// search finding no match
|
||||||
|
searchResultsDTO = new SearchResultsDTO();
|
||||||
|
service.search(searchResultsDTO, "ZZZZZZZZZYYYYYY", rootProcessGroup);
|
||||||
|
|
||||||
|
assertEquals(0, searchResultsDTO.getControllerServiceNodeResults().size());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mocks Labels including isAuthorized() and their identifier and value
|
* Mocks Labels including isAuthorized() and their identifier and value
|
||||||
*
|
*
|
||||||
|
@ -512,6 +597,32 @@ public class ControllerSearchServiceTest {
|
||||||
}).when(containingProcessGroup).getProcessors();
|
}).when(containingProcessGroup).getProcessors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setupMockedControllerService(final String controllerServiceName, final ProcessGroup containingProcessGroup, boolean authorizedToRead,
|
||||||
|
Map<PropertyDescriptor, String> properties) {
|
||||||
|
final String controllerServiceId = controllerServiceName + "Id";
|
||||||
|
final ControllerService controllerService = mock(ControllerService.class);
|
||||||
|
|
||||||
|
final ControllerServiceNode controllerServiceNode1 = mock(StandardControllerServiceNode.class);
|
||||||
|
Mockito.doReturn(authorizedToRead).when(controllerServiceNode1)
|
||||||
|
.isAuthorized(AdditionalMatchers.or(any(Authorizer.class), isNull()), eq(RequestAction.READ), AdditionalMatchers.or(any(NiFiUser.class), isNull()));
|
||||||
|
Mockito.doReturn(controllerService).when(controllerServiceNode1).getControllerServiceImplementation();
|
||||||
|
// set controller service node attributes
|
||||||
|
Mockito.doReturn(controllerServiceId).when(controllerServiceNode1).getIdentifier();
|
||||||
|
Mockito.doReturn(controllerServiceName).when(controllerServiceNode1).getName();
|
||||||
|
Mockito.doReturn(Optional.ofNullable(null)).when(controllerServiceNode1).getVersionedComponentId();
|
||||||
|
Mockito.doReturn("foo comments").when(controllerServiceNode1).getComments();
|
||||||
|
|
||||||
|
//set properties
|
||||||
|
Mockito.doReturn(properties).when(controllerServiceNode1).getRawPropertyValues();
|
||||||
|
|
||||||
|
// assign controller service node to its PG
|
||||||
|
Mockito.doReturn(new HashSet<ControllerServiceNode>() {
|
||||||
|
{
|
||||||
|
add(controllerServiceNode1);
|
||||||
|
}
|
||||||
|
}).when(containingProcessGroup).getControllerServices(anyBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mocks ProcessGroup due to isAuthorized(). The final class StandardProcessGroup can't be used.
|
* Mocks ProcessGroup due to isAuthorized(). The final class StandardProcessGroup can't be used.
|
||||||
*
|
*
|
||||||
|
|
|
@ -208,6 +208,14 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// show all controller services
|
||||||
|
if (!nfCommon.isEmpty(searchResults.controllerServiceNodeResults)) {
|
||||||
|
ul.append('<li class="search-header"><div class="search-result-icon icon"></div>Controller Services</li>');
|
||||||
|
$.each(searchResults.controllerServiceNodeResults, function (i, controllerServiceMatch) {
|
||||||
|
nfSearchAutocomplete._renderItem(ul, $.extend({}, controllerServiceMatch, { type: 'controller service' }));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// show all parameter contexts and parameters
|
// show all parameter contexts and parameters
|
||||||
if (!nfCommon.isEmpty(searchResults.parameterContextResults)) {
|
if (!nfCommon.isEmpty(searchResults.parameterContextResults)) {
|
||||||
ul.append('<li class="search-header"><div class="search-result-icon icon"></div>Parameter Contexts</li>');
|
ul.append('<li class="search-header"><div class="search-result-icon icon"></div>Parameter Contexts</li>');
|
||||||
|
|
Loading…
Reference in New Issue