use of org.apache.nifi.flowfile.FlowFilePrioritizer in project nifi by apache.
the class ControllerSearchService method search.
private ComponentSearchResultDTO search(final String searchStr, final Connection connection) {
final List<String> matches = new ArrayList<>();
// search id and name
addIfAppropriate(searchStr, connection.getIdentifier(), "Id", matches);
addIfAppropriate(searchStr, connection.getVersionedComponentId().orElse(null), "Version Control ID", matches);
addIfAppropriate(searchStr, connection.getName(), "Name", matches);
// search relationships
for (final Relationship relationship : connection.getRelationships()) {
addIfAppropriate(searchStr, relationship.getName(), "Relationship", matches);
}
// search prioritizers
final FlowFileQueue queue = connection.getFlowFileQueue();
for (final FlowFilePrioritizer comparator : queue.getPriorities()) {
addIfAppropriate(searchStr, comparator.getClass().getName(), "Prioritizer", matches);
}
// search expiration
if (StringUtils.containsIgnoreCase("expires", searchStr) || StringUtils.containsIgnoreCase("expiration", searchStr)) {
final int expirationMillis = connection.getFlowFileQueue().getFlowFileExpiration(TimeUnit.MILLISECONDS);
if (expirationMillis > 0) {
matches.add("FlowFile expiration: " + connection.getFlowFileQueue().getFlowFileExpiration());
}
}
// search back pressure
if (StringUtils.containsIgnoreCase("back pressure", searchStr) || StringUtils.containsIgnoreCase("pressure", searchStr)) {
final String backPressureDataSize = connection.getFlowFileQueue().getBackPressureDataSizeThreshold();
final Double backPressureBytes = DataUnit.parseDataSize(backPressureDataSize, DataUnit.B);
if (backPressureBytes > 0) {
matches.add("Back pressure data size: " + backPressureDataSize);
}
final long backPressureCount = connection.getFlowFileQueue().getBackPressureObjectThreshold();
if (backPressureCount > 0) {
matches.add("Back pressure count: " + backPressureCount);
}
}
// search the source
final Connectable source = connection.getSource();
addIfAppropriate(searchStr, source.getIdentifier(), "Source id", matches);
addIfAppropriate(searchStr, source.getName(), "Source name", matches);
addIfAppropriate(searchStr, source.getComments(), "Source comments", matches);
// search the destination
final Connectable destination = connection.getDestination();
addIfAppropriate(searchStr, destination.getIdentifier(), "Destination id", matches);
addIfAppropriate(searchStr, destination.getName(), "Destination name", matches);
addIfAppropriate(searchStr, destination.getComments(), "Destination comments", matches);
if (matches.isEmpty()) {
return null;
}
final ComponentSearchResultDTO result = new ComponentSearchResultDTO();
result.setId(connection.getIdentifier());
// determine the name of the search match
if (StringUtils.isNotBlank(connection.getName())) {
result.setName(connection.getName());
} else if (!connection.getRelationships().isEmpty()) {
final List<String> relationships = new ArrayList<>(connection.getRelationships().size());
for (final Relationship relationship : connection.getRelationships()) {
if (StringUtils.isNotBlank(relationship.getName())) {
relationships.add(relationship.getName());
}
}
if (!relationships.isEmpty()) {
result.setName(StringUtils.join(relationships, ", "));
}
}
// ensure a name is added
if (result.getName() == null) {
result.setName("From source " + connection.getSource().getName());
}
result.setMatches(matches);
return result;
}
use of org.apache.nifi.flowfile.FlowFilePrioritizer in project nifi by apache.
the class TestWriteAheadFlowFileRepository method testUpdatePerformance.
@Test
@Ignore("Intended only for local performance testing before/after making changes")
public void testUpdatePerformance() throws IOException, InterruptedException {
final FlowFileQueue queue = new FlowFileQueue() {
@Override
public String getIdentifier() {
return "4444";
}
@Override
public List<FlowFilePrioritizer> getPriorities() {
return null;
}
@Override
public SwapSummary recoverSwappedFlowFiles() {
return null;
}
@Override
public void purgeSwapFiles() {
}
@Override
public int getSwapFileCount() {
return 0;
}
@Override
public void setPriorities(List<FlowFilePrioritizer> newPriorities) {
}
@Override
public void setBackPressureObjectThreshold(long maxQueueSize) {
}
@Override
public long getBackPressureObjectThreshold() {
return 0;
}
@Override
public void setBackPressureDataSizeThreshold(String maxDataSize) {
}
@Override
public String getBackPressureDataSizeThreshold() {
return null;
}
@Override
public QueueSize size() {
return null;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean isActiveQueueEmpty() {
return false;
}
@Override
public QueueSize getUnacknowledgedQueueSize() {
return null;
}
@Override
public QueueSize getActiveQueueSize() {
return size();
}
@Override
public QueueSize getSwapQueueSize() {
return null;
}
@Override
public void acknowledge(FlowFileRecord flowFile) {
}
@Override
public void acknowledge(Collection<FlowFileRecord> flowFiles) {
}
@Override
public boolean isAllActiveFlowFilesPenalized() {
return false;
}
@Override
public boolean isAnyActiveFlowFilePenalized() {
return false;
}
@Override
public boolean isFull() {
return false;
}
@Override
public void put(FlowFileRecord file) {
}
@Override
public void putAll(Collection<FlowFileRecord> files) {
}
@Override
public FlowFileRecord poll(Set<FlowFileRecord> expiredRecords) {
return null;
}
@Override
public List<FlowFileRecord> poll(int maxResults, Set<FlowFileRecord> expiredRecords) {
return null;
}
@Override
public long drainQueue(Queue<FlowFileRecord> sourceQueue, List<FlowFileRecord> destination, int maxResults, Set<FlowFileRecord> expiredRecords) {
return 0;
}
@Override
public List<FlowFileRecord> poll(FlowFileFilter filter, Set<FlowFileRecord> expiredRecords) {
return null;
}
@Override
public String getFlowFileExpiration() {
return null;
}
@Override
public int getFlowFileExpiration(TimeUnit timeUnit) {
return 0;
}
@Override
public void setFlowFileExpiration(String flowExpirationPeriod) {
}
@Override
public DropFlowFileStatus dropFlowFiles(String requestIdentifier, String requestor) {
return null;
}
@Override
public DropFlowFileStatus getDropFlowFileStatus(String requestIdentifier) {
return null;
}
@Override
public DropFlowFileStatus cancelDropFlowFileRequest(String requestIdentifier) {
return null;
}
@Override
public ListFlowFileStatus listFlowFiles(String requestIdentifier, int maxResults) {
return null;
}
@Override
public ListFlowFileStatus getListFlowFileStatus(String requestIdentifier) {
return null;
}
@Override
public ListFlowFileStatus cancelListFlowFileRequest(String requestIdentifier) {
return null;
}
@Override
public FlowFileRecord getFlowFile(String flowFileUuid) throws IOException {
return null;
}
@Override
public void verifyCanList() throws IllegalStateException {
}
};
final int numPartitions = 16;
final int numThreads = 8;
final int totalUpdates = 160_000_000;
final int batchSize = 10;
final Path path = Paths.get("target/minimal-locking-repo");
deleteRecursively(path.toFile());
assertTrue(path.toFile().mkdirs());
final ResourceClaimManager claimManager = new StandardResourceClaimManager();
final RepositoryRecordSerdeFactory serdeFactory = new RepositoryRecordSerdeFactory(claimManager);
final WriteAheadRepository<RepositoryRecord> repo = new MinimalLockingWriteAheadLog<>(path, numPartitions, serdeFactory, null);
final Collection<RepositoryRecord> initialRecs = repo.recoverRecords();
assertTrue(initialRecs.isEmpty());
final int updateCountPerThread = totalUpdates / numThreads;
final Thread[] threads = new Thread[numThreads];
for (int j = 0; j < 2; j++) {
for (int i = 0; i < numThreads; i++) {
final Thread t = new Thread(new Runnable() {
@Override
public void run() {
final List<RepositoryRecord> records = new ArrayList<>();
final int numBatches = updateCountPerThread / batchSize;
final MockFlowFile baseFlowFile = new MockFlowFile(0L);
for (int i = 0; i < numBatches; i++) {
records.clear();
for (int k = 0; k < batchSize; k++) {
final FlowFileRecord flowFile = new MockFlowFile(i % 100_000, baseFlowFile);
final String uuid = flowFile.getAttribute("uuid");
final StandardRepositoryRecord record = new StandardRepositoryRecord(null, flowFile);
record.setDestination(queue);
final Map<String, String> updatedAttrs = Collections.singletonMap("uuid", uuid);
record.setWorking(flowFile, updatedAttrs);
records.add(record);
}
try {
repo.update(records, false);
} catch (IOException e) {
e.printStackTrace();
Assert.fail(e.toString());
}
}
}
});
t.setDaemon(true);
threads[i] = t;
}
final long start = System.nanoTime();
for (final Thread t : threads) {
t.start();
}
for (final Thread t : threads) {
t.join();
}
final long millis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
if (j == 0) {
System.out.println(millis + " ms to insert " + updateCountPerThread * numThreads + " updates using " + numPartitions + " partitions and " + numThreads + " threads, *as a warmup!*");
} else {
System.out.println(millis + " ms to insert " + updateCountPerThread * numThreads + " updates using " + numPartitions + " partitions and " + numThreads + " threads");
}
}
}
use of org.apache.nifi.flowfile.FlowFilePrioritizer in project nifi by apache.
the class RelationshipAuditor method extractConfiguredPropertyValues.
/**
* Extracts configured settings from the specified connection only if they have also been specified in the connectionDTO.
*
* @param connection connection
* @param connectionDTO dto
* @return properties
*/
private Map<String, String> extractConfiguredPropertyValues(Connection connection, ConnectionDTO connectionDTO) {
Map<String, String> values = new HashMap<>();
if (connectionDTO.getName() != null) {
values.put(NAME, connection.getName());
}
if (connectionDTO.getFlowFileExpiration() != null) {
values.put(FLOW_FILE_EXPIRATION, String.valueOf(connection.getFlowFileQueue().getFlowFileExpiration()));
}
if (connectionDTO.getBackPressureObjectThreshold() != null) {
values.put(BACK_PRESSURE_OBJECT_THRESHOLD, String.valueOf(connection.getFlowFileQueue().getBackPressureObjectThreshold()));
}
if (connectionDTO.getBackPressureDataSizeThreshold() != null) {
values.put(BACK_PRESSURE_DATA_SIZE_THRESHOLD, String.valueOf(connection.getFlowFileQueue().getBackPressureDataSizeThreshold()));
}
if (connectionDTO.getPrioritizers() != null) {
List<String> prioritizers = new ArrayList<>();
for (FlowFilePrioritizer prioritizer : connection.getFlowFileQueue().getPriorities()) {
prioritizers.add(prioritizer.getClass().getCanonicalName());
}
values.put(PRIORITIZERS, StringUtils.join(prioritizers, ", "));
}
return values;
}
use of org.apache.nifi.flowfile.FlowFilePrioritizer in project nifi by apache.
the class StandardFlowFileQueue method setPriorities.
@Override
public void setPriorities(final List<FlowFilePrioritizer> newPriorities) {
writeLock.lock();
try {
final PriorityQueue<FlowFileRecord> newQueue = new PriorityQueue<>(Math.max(20, activeQueue.size()), new Prioritizer(newPriorities));
newQueue.addAll(activeQueue);
activeQueue = newQueue;
priorities.clear();
priorities.addAll(newPriorities);
} finally {
writeLock.unlock("setPriorities");
}
}
use of org.apache.nifi.flowfile.FlowFilePrioritizer in project nifi by apache.
the class StandardFlowSynchronizer method updateProcessGroup.
private ProcessGroup updateProcessGroup(final FlowController controller, final ProcessGroup parentGroup, final Element processGroupElement, final StringEncryptor encryptor, final FlowEncodingVersion encodingVersion) throws ProcessorInstantiationException {
// get the parent group ID
final String parentId = (parentGroup == null) ? null : parentGroup.getIdentifier();
// get the process group
final ProcessGroupDTO processGroupDto = FlowFromDOMFactory.getProcessGroup(parentId, processGroupElement, encryptor, encodingVersion);
// update the process group
if (parentId == null) {
/*
* Labels are not included in the "inherit flow" algorithm, so we cannot
* blindly update them because they may not exist in the current flow.
* Therefore, we first remove all labels, and then let the updating
* process add labels defined in the new flow.
*/
final ProcessGroup root = controller.getGroup(controller.getRootGroupId());
for (final Label label : root.findAllLabels()) {
label.getProcessGroup().removeLabel(label);
}
}
// update the process group
controller.updateProcessGroup(processGroupDto);
// get the real process group and ID
final ProcessGroup processGroup = controller.getGroup(processGroupDto.getId());
// determine the scheduled state of all of the Controller Service
final List<Element> controllerServiceNodeList = getChildrenByTagName(processGroupElement, "controllerService");
final Set<ControllerServiceNode> toDisable = new HashSet<>();
final Set<ControllerServiceNode> toEnable = new HashSet<>();
for (final Element serviceElement : controllerServiceNodeList) {
final ControllerServiceDTO dto = FlowFromDOMFactory.getControllerService(serviceElement, encryptor);
final ControllerServiceNode serviceNode = processGroup.getControllerService(dto.getId());
// Check if the controller service is in the correct state. We consider it the correct state if
// we are in a transitional state and heading in the right direction or already in the correct state.
// E.g., it is the correct state if it should be 'DISABLED' and it is either DISABLED or DISABLING.
final ControllerServiceState serviceState = getFinalTransitionState(serviceNode.getState());
final ControllerServiceState clusterState = getFinalTransitionState(ControllerServiceState.valueOf(dto.getState()));
if (serviceState != clusterState) {
switch(clusterState) {
case DISABLED:
toDisable.add(serviceNode);
break;
case ENABLED:
toEnable.add(serviceNode);
break;
}
}
}
controller.disableControllerServicesAsync(toDisable);
controller.enableControllerServices(toEnable);
// processors & ports cannot be updated - they must be the same. Except for the scheduled state.
final List<Element> processorNodeList = getChildrenByTagName(processGroupElement, "processor");
for (final Element processorElement : processorNodeList) {
final ProcessorDTO dto = FlowFromDOMFactory.getProcessor(processorElement, encryptor);
final ProcessorNode procNode = processGroup.getProcessor(dto.getId());
updateNonFingerprintedProcessorSettings(procNode, dto);
if (!procNode.getScheduledState().name().equals(dto.getState())) {
try {
switch(ScheduledState.valueOf(dto.getState())) {
case DISABLED:
// switch processor do disabled. This means we have to stop it (if it's already stopped, this method does nothing),
// and then we have to disable it.
controller.stopProcessor(procNode.getProcessGroupIdentifier(), procNode.getIdentifier());
procNode.getProcessGroup().disableProcessor(procNode);
break;
case RUNNING:
// we want to run now. Make sure processor is not disabled and then start it.
procNode.getProcessGroup().enableProcessor(procNode);
controller.startProcessor(procNode.getProcessGroupIdentifier(), procNode.getIdentifier(), false);
break;
case STOPPED:
if (procNode.getScheduledState() == ScheduledState.DISABLED) {
procNode.getProcessGroup().enableProcessor(procNode);
} else if (procNode.getScheduledState() == ScheduledState.RUNNING) {
controller.stopProcessor(procNode.getProcessGroupIdentifier(), procNode.getIdentifier());
}
break;
}
} catch (final IllegalStateException ise) {
logger.error("Failed to change Scheduled State of {} from {} to {} due to {}", procNode, procNode.getScheduledState().name(), dto.getState(), ise.toString());
logger.error("", ise);
// create bulletin for the Processor Node
controller.getBulletinRepository().addBulletin(BulletinFactory.createBulletin(procNode, "Node Reconnection", Severity.ERROR.name(), "Failed to change Scheduled State of " + procNode + " from " + procNode.getScheduledState().name() + " to " + dto.getState() + " due to " + ise.toString()));
// create bulletin at Controller level.
controller.getBulletinRepository().addBulletin(BulletinFactory.createBulletin("Node Reconnection", Severity.ERROR.name(), "Failed to change Scheduled State of " + procNode + " from " + procNode.getScheduledState().name() + " to " + dto.getState() + " due to " + ise.toString()));
}
}
}
final List<Element> inputPortList = getChildrenByTagName(processGroupElement, "inputPort");
for (final Element portElement : inputPortList) {
final PortDTO dto = FlowFromDOMFactory.getPort(portElement);
final Port port = processGroup.getInputPort(dto.getId());
if (!port.getScheduledState().name().equals(dto.getState())) {
switch(ScheduledState.valueOf(dto.getState())) {
case DISABLED:
// switch processor do disabled. This means we have to stop it (if it's already stopped, this method does nothing),
// and then we have to disable it.
controller.stopConnectable(port);
port.getProcessGroup().disableInputPort(port);
break;
case RUNNING:
// we want to run now. Make sure processor is not disabled and then start it.
port.getProcessGroup().enableInputPort(port);
controller.startConnectable(port);
break;
case STOPPED:
if (port.getScheduledState() == ScheduledState.DISABLED) {
port.getProcessGroup().enableInputPort(port);
} else if (port.getScheduledState() == ScheduledState.RUNNING) {
controller.stopConnectable(port);
}
break;
}
}
}
final List<Element> outputPortList = getChildrenByTagName(processGroupElement, "outputPort");
for (final Element portElement : outputPortList) {
final PortDTO dto = FlowFromDOMFactory.getPort(portElement);
final Port port = processGroup.getOutputPort(dto.getId());
if (!port.getScheduledState().name().equals(dto.getState())) {
switch(ScheduledState.valueOf(dto.getState())) {
case DISABLED:
// switch processor do disabled. This means we have to stop it (if it's already stopped, this method does nothing),
// and then we have to disable it.
controller.stopConnectable(port);
port.getProcessGroup().disableOutputPort(port);
break;
case RUNNING:
// we want to run now. Make sure processor is not disabled and then start it.
port.getProcessGroup().enableOutputPort(port);
controller.startConnectable(port);
break;
case STOPPED:
if (port.getScheduledState() == ScheduledState.DISABLED) {
port.getProcessGroup().enableOutputPort(port);
} else if (port.getScheduledState() == ScheduledState.RUNNING) {
controller.stopConnectable(port);
}
break;
}
}
}
// Update scheduled state of Remote Group Ports
final List<Element> remoteProcessGroupList = getChildrenByTagName(processGroupElement, "remoteProcessGroup");
for (final Element remoteGroupElement : remoteProcessGroupList) {
final RemoteProcessGroupDTO remoteGroupDto = FlowFromDOMFactory.getRemoteProcessGroup(remoteGroupElement, encryptor);
final RemoteProcessGroup rpg = processGroup.getRemoteProcessGroup(remoteGroupDto.getId());
// input ports
final List<Element> inputPortElements = getChildrenByTagName(remoteGroupElement, "inputPort");
for (final Element inputPortElement : inputPortElements) {
final RemoteProcessGroupPortDescriptor portDescriptor = FlowFromDOMFactory.getRemoteProcessGroupPort(inputPortElement);
final String inputPortId = portDescriptor.getId();
final RemoteGroupPort inputPort = rpg.getInputPort(inputPortId);
if (inputPort == null) {
continue;
}
if (portDescriptor.isTransmitting()) {
if (inputPort.getScheduledState() != ScheduledState.RUNNING && inputPort.getScheduledState() != ScheduledState.STARTING) {
rpg.startTransmitting(inputPort);
}
} else if (inputPort.getScheduledState() != ScheduledState.STOPPED && inputPort.getScheduledState() != ScheduledState.STOPPING) {
rpg.stopTransmitting(inputPort);
}
}
// output ports
final List<Element> outputPortElements = getChildrenByTagName(remoteGroupElement, "outputPort");
for (final Element outputPortElement : outputPortElements) {
final RemoteProcessGroupPortDescriptor portDescriptor = FlowFromDOMFactory.getRemoteProcessGroupPort(outputPortElement);
final String outputPortId = portDescriptor.getId();
final RemoteGroupPort outputPort = rpg.getOutputPort(outputPortId);
if (outputPort == null) {
continue;
}
if (portDescriptor.isTransmitting()) {
if (outputPort.getScheduledState() != ScheduledState.RUNNING && outputPort.getScheduledState() != ScheduledState.STARTING) {
rpg.startTransmitting(outputPort);
}
} else if (outputPort.getScheduledState() != ScheduledState.STOPPED && outputPort.getScheduledState() != ScheduledState.STOPPING) {
rpg.stopTransmitting(outputPort);
}
}
}
// add labels
final List<Element> labelNodeList = getChildrenByTagName(processGroupElement, "label");
for (final Element labelElement : labelNodeList) {
final LabelDTO labelDTO = FlowFromDOMFactory.getLabel(labelElement);
final Label label = controller.createLabel(labelDTO.getId(), labelDTO.getLabel());
label.setStyle(labelDTO.getStyle());
label.setPosition(new Position(labelDTO.getPosition().getX(), labelDTO.getPosition().getY()));
label.setVersionedComponentId(labelDTO.getVersionedComponentId());
if (labelDTO.getWidth() != null && labelDTO.getHeight() != null) {
label.setSize(new Size(labelDTO.getWidth(), labelDTO.getHeight()));
}
processGroup.addLabel(label);
}
// update nested process groups (recursively)
final List<Element> nestedProcessGroupNodeList = getChildrenByTagName(processGroupElement, "processGroup");
for (final Element nestedProcessGroupElement : nestedProcessGroupNodeList) {
updateProcessGroup(controller, processGroup, nestedProcessGroupElement, encryptor, encodingVersion);
}
// update connections
final List<Element> connectionNodeList = getChildrenByTagName(processGroupElement, "connection");
for (final Element connectionElement : connectionNodeList) {
final ConnectionDTO dto = FlowFromDOMFactory.getConnection(connectionElement);
final Connection connection = processGroup.getConnection(dto.getId());
connection.setName(dto.getName());
connection.setProcessGroup(processGroup);
if (dto.getLabelIndex() != null) {
connection.setLabelIndex(dto.getLabelIndex());
}
if (dto.getzIndex() != null) {
connection.setZIndex(dto.getzIndex());
}
final List<Position> bendPoints = new ArrayList<>();
for (final PositionDTO bend : dto.getBends()) {
bendPoints.add(new Position(bend.getX(), bend.getY()));
}
connection.setBendPoints(bendPoints);
List<FlowFilePrioritizer> newPrioritizers = null;
final List<String> prioritizers = dto.getPrioritizers();
if (prioritizers != null) {
final List<String> newPrioritizersClasses = new ArrayList<>(prioritizers);
newPrioritizers = new ArrayList<>();
for (final String className : newPrioritizersClasses) {
try {
newPrioritizers.add(controller.createPrioritizer(className));
} catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException("Unable to set prioritizer " + className + ": " + e);
}
}
}
if (newPrioritizers != null) {
connection.getFlowFileQueue().setPriorities(newPrioritizers);
}
if (dto.getBackPressureObjectThreshold() != null) {
connection.getFlowFileQueue().setBackPressureObjectThreshold(dto.getBackPressureObjectThreshold());
}
if (dto.getBackPressureDataSizeThreshold() != null && !dto.getBackPressureDataSizeThreshold().trim().isEmpty()) {
connection.getFlowFileQueue().setBackPressureDataSizeThreshold(dto.getBackPressureDataSizeThreshold());
}
if (dto.getFlowFileExpiration() != null) {
connection.getFlowFileQueue().setFlowFileExpiration(dto.getFlowFileExpiration());
}
}
// Replace the templates with those from the proposed flow
final List<Element> templateNodeList = getChildrenByTagName(processGroupElement, "template");
for (final Element templateElement : templateNodeList) {
final TemplateDTO templateDto = TemplateUtils.parseDto(templateElement);
final Template template = new Template(templateDto);
// This just makes sure that they do.
if (processGroup.getTemplate(template.getIdentifier()) != null) {
processGroup.removeTemplate(template);
}
processGroup.addTemplate(template);
}
return processGroup;
}
Aggregations