|
18 | 18 |
|
19 | 19 | import org.apache.nifi.annotation.behavior.DynamicProperties;
|
20 | 20 | import org.apache.nifi.annotation.behavior.DynamicProperty;
|
| 21 | +import org.apache.nifi.annotation.behavior.DynamicRelationship; |
21 | 22 | import org.apache.nifi.components.ConfigurableComponent;
|
22 | 23 | import org.apache.nifi.components.PropertyDescriptor;
|
| 24 | +import org.apache.nifi.connectable.Connectable; |
| 25 | +import org.apache.nifi.connectable.ConnectableType; |
| 26 | +import org.apache.nifi.connectable.Connection; |
23 | 27 | import org.apache.nifi.controller.ComponentNode;
|
24 | 28 | import org.apache.nifi.controller.ProcessorNode;
|
25 | 29 | import org.apache.nifi.controller.flow.FlowManager;
|
|
36 | 40 | import org.apache.nifi.flow.VersionedProcessGroup;
|
37 | 41 | import org.apache.nifi.flow.VersionedProcessor;
|
38 | 42 | import org.apache.nifi.flow.VersionedReportingTask;
|
| 43 | +import org.apache.nifi.groups.ProcessGroup; |
| 44 | +import org.apache.nifi.processor.Processor; |
39 | 45 | import org.apache.nifi.processor.Relationship;
|
40 | 46 | import org.apache.nifi.registry.flow.diff.DifferenceType;
|
41 | 47 | import org.apache.nifi.registry.flow.diff.FlowDifference;
|
42 | 48 | import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedComponent;
|
| 49 | +import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedConnection; |
43 | 50 | import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedControllerService;
|
44 | 51 | import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedProcessor;
|
45 | 52 |
|
@@ -96,7 +103,8 @@ public static boolean isEnvironmentalChange(final FlowDifference difference, fin
|
96 | 103 | || isStaticPropertyRemoved(difference, flowManager)
|
97 | 104 | || isControllerServiceCreatedForNewProperty(difference, evaluatedContext)
|
98 | 105 | || isPropertyParameterizationRename(difference, evaluatedContext)
|
99 |
| - || isPropertyRenameWithMatchingValue(difference, evaluatedContext); |
| 106 | + || isPropertyRenameWithMatchingValue(difference, evaluatedContext) |
| 107 | + || isSelectedRelationshipChangeForNewRelationship(difference, flowManager); |
100 | 108 | }
|
101 | 109 |
|
102 | 110 | private static boolean isSensitivePropertyDueToGhosting(final FlowDifference difference, final FlowManager flowManager) {
|
@@ -441,6 +449,97 @@ public static boolean isNewRelationshipAutoTerminatedAndDefaulted(final FlowDiff
|
441 | 449 | return true;
|
442 | 450 | }
|
443 | 451 |
|
| 452 | + private static boolean isSelectedRelationshipChangeForNewRelationship(final FlowDifference difference, final FlowManager flowManager) { |
| 453 | + if (difference.getDifferenceType() != DifferenceType.SELECTED_RELATIONSHIPS_CHANGED) { |
| 454 | + return false; |
| 455 | + } |
| 456 | + |
| 457 | + if (!(difference.getComponentA() instanceof VersionedConnection connectionA)) { |
| 458 | + return false; |
| 459 | + } |
| 460 | + |
| 461 | + if (!(difference.getComponentB() instanceof InstantiatedVersionedConnection connectionB)) { |
| 462 | + return false; |
| 463 | + } |
| 464 | + |
| 465 | + final Set<String> selectedA = new HashSet<>(replaceNull(connectionA.getSelectedRelationships(), Collections.emptySet())); |
| 466 | + final Set<String> selectedB = new HashSet<>(replaceNull(connectionB.getSelectedRelationships(), Collections.emptySet())); |
| 467 | + |
| 468 | + final Set<String> newlySelected = new HashSet<>(selectedB); |
| 469 | + newlySelected.removeAll(selectedA); |
| 470 | + if (newlySelected.isEmpty()) { |
| 471 | + return false; |
| 472 | + } |
| 473 | + |
| 474 | + final Set<String> removedRelationships = new HashSet<>(selectedA); |
| 475 | + removedRelationships.removeAll(selectedB); |
| 476 | + |
| 477 | + if (flowManager == null) { |
| 478 | + return false; |
| 479 | + } |
| 480 | + |
| 481 | + final String connectionInstanceId = connectionB.getInstanceIdentifier(); |
| 482 | + final String connectionGroupId = connectionB.getInstanceGroupId(); |
| 483 | + if (connectionInstanceId == null || connectionGroupId == null) { |
| 484 | + return false; |
| 485 | + } |
| 486 | + |
| 487 | + final ProcessGroup processGroup = flowManager.getGroup(connectionGroupId); |
| 488 | + if (processGroup == null) { |
| 489 | + return false; |
| 490 | + } |
| 491 | + |
| 492 | + final Connection connection = processGroup.getConnection(connectionInstanceId); |
| 493 | + if (connection == null) { |
| 494 | + return false; |
| 495 | + } |
| 496 | + |
| 497 | + final Connectable source = connection.getSource(); |
| 498 | + if (source == null || source.getConnectableType() != ConnectableType.PROCESSOR) { |
| 499 | + return false; |
| 500 | + } |
| 501 | + |
| 502 | + final ProcessorNode processorNode = flowManager.getProcessorNode(source.getIdentifier()); |
| 503 | + if (processorNode == null) { |
| 504 | + return false; |
| 505 | + } |
| 506 | + |
| 507 | + final Processor processor = processorNode.getProcessor(); |
| 508 | + if (processor != null) { |
| 509 | + final Class<?> processorClass = processor.getClass(); |
| 510 | + if (processorClass.isAnnotationPresent(DynamicRelationship.class)) { |
| 511 | + return false; |
| 512 | + } |
| 513 | + } |
| 514 | + |
| 515 | + for (final String relationshipName : newlySelected) { |
| 516 | + final Relationship relationship = processorNode.getRelationship(relationshipName); |
| 517 | + if (relationship == null) { |
| 518 | + return false; |
| 519 | + } |
| 520 | + |
| 521 | + if (processorNode.isAutoTerminated(relationship)) { |
| 522 | + return false; |
| 523 | + } |
| 524 | + |
| 525 | + final Set<Connection> relationshipConnections = replaceNull(processorNode.getConnections(relationship), Collections.emptySet()); |
| 526 | + for (final Connection relationshipConnection : relationshipConnections) { |
| 527 | + if (!relationshipConnection.getIdentifier().equals(connection.getIdentifier())) { |
| 528 | + return false; |
| 529 | + } |
| 530 | + } |
| 531 | + } |
| 532 | + |
| 533 | + for (final String removedRelationshipName : removedRelationships) { |
| 534 | + final Relationship removedRelationship = processorNode.getRelationship(removedRelationshipName); |
| 535 | + if (removedRelationship != null) { |
| 536 | + return false; |
| 537 | + } |
| 538 | + } |
| 539 | + |
| 540 | + return true; |
| 541 | + } |
| 542 | + |
444 | 543 | private static <T> T replaceNull(final T value, final T replacement) {
|
445 | 544 | return value == null ? replacement : value;
|
446 | 545 | }
|
|
0 commit comments