39
39
import org .apache .nifi .flow .VersionedPort ;
40
40
import org .apache .nifi .flow .VersionedProcessGroup ;
41
41
import org .apache .nifi .flow .VersionedProcessor ;
42
- import org .apache .nifi .flow .VersionedReportingTask ;
42
+ import org .apache .nifi .flow .VersionedPropertyDescriptor ;
43
43
import org .apache .nifi .groups .ProcessGroup ;
44
44
import org .apache .nifi .processor .Processor ;
45
45
import org .apache .nifi .processor .Relationship ;
63
63
import java .util .Set ;
64
64
import java .util .function .Predicate ;
65
65
import java .util .regex .Pattern ;
66
- import java .util .stream .Collectors ;
67
66
68
67
public class FlowDifferenceFilters {
69
68
@@ -113,19 +112,25 @@ private static boolean isSensitivePropertyDueToGhosting(final FlowDifference dif
113
112
return false ;
114
113
}
115
114
116
- final String componentAId = difference .getComponentA ().getInstanceIdentifier ();
117
- if (componentAId != null ) {
118
- final ComponentNode componentNode = getComponent (flowManager , difference .getComponentA ().getComponentType (), componentAId );
119
- if (componentNode != null && componentNode .isExtensionMissing ()) {
120
- return true ;
115
+ final VersionedComponent componentA = difference .getComponentA ();
116
+ if (componentA != null ) {
117
+ final String componentAId = componentA .getInstanceIdentifier ();
118
+ if (componentAId != null ) {
119
+ final ComponentNode componentNode = getComponent (flowManager , componentA .getComponentType (), componentAId );
120
+ if (componentNode != null && componentNode .isExtensionMissing ()) {
121
+ return true ;
122
+ }
121
123
}
122
124
}
123
125
124
- final String componentBId = difference .getComponentB ().getInstanceIdentifier ();
125
- if (componentBId != null ) {
126
- final ComponentNode componentNode = getComponent (flowManager , difference .getComponentA ().getComponentType (), componentBId );
127
- if (componentNode != null && componentNode .isExtensionMissing ()) {
128
- return true ;
126
+ final VersionedComponent componentB = difference .getComponentB ();
127
+ if (componentB != null ) {
128
+ final String componentBId = componentB .getInstanceIdentifier ();
129
+ if (componentBId != null ) {
130
+ final ComponentNode componentNode = getComponent (flowManager , componentB .getComponentType (), componentBId );
131
+ if (componentNode != null && componentNode .isExtensionMissing ()) {
132
+ return true ;
133
+ }
129
134
}
130
135
}
131
136
@@ -682,34 +687,27 @@ public static EnvironmentalChangeContext buildEnvironmentalChangeContext(final C
682
687
return EnvironmentalChangeContext .empty ();
683
688
}
684
689
685
- final Set <String > serviceIdsReferencedByNewProperties = new HashSet <>();
686
690
final Map <String , List <PropertyDiffInfo >> parameterizedAddsByComponent = new HashMap <>();
687
691
final Map <String , List <PropertyDiffInfo >> parameterizationRemovalsByComponent = new HashMap <>();
692
+ final Map <String , List <PropertyDiffInfo >> controllerServicePropertyAddsByValue = new HashMap <>();
688
693
final Map <String , List <PropertyDiffInfo >> propertyAddsByComponent = new HashMap <>();
689
694
final Map <String , List <PropertyDiffInfo >> propertyRemovalsByComponent = new HashMap <>();
690
695
691
696
for (final FlowDifference difference : differences ) {
692
697
if (difference .getDifferenceType () == DifferenceType .PROPERTY_ADDED ) {
693
- final ComponentNode componentNode = Optional .ofNullable (getComponent (flowManager , difference .getComponentB ()))
694
- .orElseGet (() -> getComponent (flowManager , difference .getComponentA ()));
695
- if (componentNode != null ) {
696
- final Optional <String > fieldNameOptional = difference .getFieldName ();
697
- if (fieldNameOptional .isPresent ()) {
698
- final PropertyDescriptor propertyDescriptor = componentNode .getPropertyDescriptor (fieldNameOptional .get ());
699
- if (propertyDescriptor != null && !propertyDescriptor .isDynamic () && propertyDescriptor .getControllerServiceDefinition () != null ) {
700
- final Object valueB = difference .getValueB ();
701
- if (valueB instanceof String serviceId ) {
702
- serviceIdsReferencedByNewProperties .add (serviceId );
703
- }
704
- }
705
- }
706
- }
707
-
708
698
final Optional <String > componentIdOptional = getComponentInstanceIdentifier (difference );
709
699
if (componentIdOptional .isPresent ()) {
710
700
final PropertyDiffInfo diffInfo = new PropertyDiffInfo (getPropertyValue (difference , false ), difference );
711
701
propertyAddsByComponent .computeIfAbsent (componentIdOptional .get (), key -> new ArrayList <>()).add (diffInfo );
712
702
}
703
+
704
+ final Optional <String > propertyValue = getPropertyValue (difference , false );
705
+ if (propertyValue .isPresent ()
706
+ && !isParameterReference (propertyValue .get ())
707
+ && isControllerServiceProperty (difference , flowManager )) {
708
+ controllerServicePropertyAddsByValue .computeIfAbsent (propertyValue .get (), key -> new ArrayList <>())
709
+ .add (new PropertyDiffInfo (propertyValue , difference ));
710
+ }
713
711
}
714
712
715
713
if (difference .getDifferenceType () == DifferenceType .PROPERTY_REMOVED ) {
@@ -743,16 +741,17 @@ public static EnvironmentalChangeContext buildEnvironmentalChangeContext(final C
743
741
}
744
742
}
745
743
746
- final Set <String > serviceIdsWithMatchingAdditions ;
747
- if (!serviceIdsReferencedByNewProperties .isEmpty ()) {
748
- serviceIdsWithMatchingAdditions = differences .stream ()
749
- .filter (diff -> diff .getDifferenceType () == DifferenceType .COMPONENT_ADDED )
750
- .map (FlowDifferenceFilters ::extractControllerServiceIdentifier )
751
- .filter (Objects ::nonNull )
752
- .filter (serviceIdsReferencedByNewProperties ::contains )
753
- .collect (Collectors .toSet ());
754
- } else {
755
- serviceIdsWithMatchingAdditions = Collections .emptySet ();
744
+ final Set <String > serviceIdsWithMatchingAdditions = new HashSet <>();
745
+ for (final FlowDifference difference : differences ) {
746
+ if (difference .getDifferenceType () != DifferenceType .COMPONENT_ADDED ) {
747
+ continue ;
748
+ }
749
+
750
+ for (final String candidateId : getControllerServiceIdentifiers (difference )) {
751
+ if (controllerServicePropertyAddsByValue .containsKey (candidateId )) {
752
+ serviceIdsWithMatchingAdditions .add (candidateId );
753
+ }
754
+ }
756
755
}
757
756
758
757
final Set <FlowDifference > parameterizedPropertyRenameDifferences = new HashSet <>();
@@ -851,41 +850,50 @@ private static boolean isControllerServiceCreatedForNewPropertyInternal(final Fl
851
850
}
852
851
853
852
if (difference .getDifferenceType () == DifferenceType .PROPERTY_ADDED ) {
854
- final Object valueB = difference .getValueB ();
855
- return valueB != null && context .serviceIdsCreatedForNewProperties ().contains (valueB );
853
+ return getPropertyValue (difference , false )
854
+ .filter (value -> context .serviceIdsCreatedForNewProperties ().contains (value ))
855
+ .isPresent ();
856
856
}
857
857
858
858
if (difference .getDifferenceType () == DifferenceType .COMPONENT_ADDED ) {
859
- final String serviceIdentifier = extractControllerServiceIdentifier (difference );
860
- return serviceIdentifier != null && context .serviceIdsCreatedForNewProperties ().contains (serviceIdentifier );
859
+ for (final String candidateId : getControllerServiceIdentifiers (difference )) {
860
+ if (context .serviceIdsCreatedForNewProperties ().contains (candidateId )) {
861
+ return true ;
862
+ }
863
+ }
864
+ return false ;
861
865
}
862
866
863
867
return false ;
864
868
}
865
869
866
- private static String extractControllerServiceIdentifier (final FlowDifference difference ) {
867
- final String identifierFromComponentB = extractControllerServiceIdentifier (difference .getComponentB ());
868
- if (identifierFromComponentB != null ) {
869
- return identifierFromComponentB ;
870
- }
870
+ private static Set <String > getControllerServiceIdentifiers (final FlowDifference difference ) {
871
+ final Set <String > identifiers = new HashSet <>();
871
872
872
- return extractControllerServiceIdentifier (difference .getComponentA ());
873
+ addControllerServiceIdentifiers (difference .getComponentB (), identifiers );
874
+ addControllerServiceIdentifiers (difference .getComponentA (), identifiers );
875
+
876
+ return identifiers ;
873
877
}
874
878
875
- private static String extractControllerServiceIdentifier (final VersionedComponent component ) {
876
- if (component instanceof InstantiatedVersionedControllerService ) {
877
- final InstantiatedVersionedControllerService instantiatedControllerService = (InstantiatedVersionedControllerService ) component ;
879
+ private static void addControllerServiceIdentifiers (final VersionedComponent component , final Set <String > identifiers ) {
880
+ if (component == null ) {
881
+ return ;
882
+ }
883
+
884
+ if (component instanceof InstantiatedVersionedControllerService instantiatedControllerService ) {
878
885
final String instanceIdentifier = instantiatedControllerService .getInstanceIdentifier ();
879
886
if (instanceIdentifier != null ) {
880
- return instanceIdentifier ;
887
+ identifiers . add ( instanceIdentifier ) ;
881
888
}
882
889
}
883
890
884
891
if (component instanceof VersionedControllerService ) {
885
- return component .getIdentifier ();
892
+ final String identifier = component .getIdentifier ();
893
+ if (identifier != null ) {
894
+ identifiers .add (identifier );
895
+ }
886
896
}
887
-
888
- return null ;
889
897
}
890
898
891
899
public static boolean isPropertyParameterizationRename (final FlowDifference difference , final EnvironmentalChangeContext context ) {
@@ -985,6 +993,59 @@ private static Optional<String> getPropertyValue(final FlowDifference difference
985
993
return Optional .empty ();
986
994
}
987
995
996
+ private static Optional <PropertyDescriptor > getComponentPropertyDescriptor (final FlowManager flowManager , final FlowDifference difference , final String propertyName ) {
997
+ final ComponentNode componentNode = Optional .ofNullable (getComponent (flowManager , difference .getComponentB ()))
998
+ .orElseGet (() -> getComponent (flowManager , difference .getComponentA ()));
999
+
1000
+ if (componentNode == null ) {
1001
+ return Optional .empty ();
1002
+ }
1003
+
1004
+ return Optional .ofNullable (componentNode .getPropertyDescriptor (propertyName ));
1005
+ }
1006
+
1007
+ private static Optional <VersionedPropertyDescriptor > getVersionedPropertyDescriptor (final FlowDifference difference , final boolean fromComponentA ) {
1008
+ final VersionedComponent component = fromComponentA ? difference .getComponentA () : difference .getComponentB ();
1009
+ final Map <String , VersionedPropertyDescriptor > descriptors = getPropertyDescriptors (component );
1010
+ if (descriptors == null || descriptors .isEmpty ()) {
1011
+ return Optional .empty ();
1012
+ }
1013
+
1014
+ final Optional <String > fieldNameOptional = difference .getFieldName ();
1015
+ if (fieldNameOptional .isEmpty ()) {
1016
+ return Optional .empty ();
1017
+ }
1018
+
1019
+ final String fieldName = fieldNameOptional .get ();
1020
+ VersionedPropertyDescriptor descriptor = descriptors .get (fieldName );
1021
+ if (descriptor == null ) {
1022
+ descriptor = descriptors .values ().stream ()
1023
+ .filter (candidate -> fieldName .equals (candidate .getName ()) || fieldName .equals (candidate .getDisplayName ()))
1024
+ .findFirst ()
1025
+ .orElse (null );
1026
+ }
1027
+
1028
+ return Optional .ofNullable (descriptor );
1029
+ }
1030
+
1031
+ private static Map <String , VersionedPropertyDescriptor > getPropertyDescriptors (final VersionedComponent component ) {
1032
+ final Map <String , VersionedPropertyDescriptor > descriptors ;
1033
+
1034
+ if (component == null ) {
1035
+ descriptors = Collections .emptyMap ();
1036
+ } else if (component instanceof VersionedConfigurableComponent configurableComponent ) {
1037
+ descriptors = configurableComponent .getPropertyDescriptors ();
1038
+ } else if (component instanceof VersionedProcessor processor ) {
1039
+ descriptors = processor .getPropertyDescriptors ();
1040
+ } else if (component instanceof VersionedControllerService controllerService ) {
1041
+ descriptors = controllerService .getPropertyDescriptors ();
1042
+ } else {
1043
+ descriptors = Collections .emptyMap ();
1044
+ }
1045
+
1046
+ return descriptors == null ? Collections .emptyMap () : descriptors ;
1047
+ }
1048
+
988
1049
private static Map <String , String > getProperties (final VersionedComponent component ) {
989
1050
final Map <String , String > properties ;
990
1051
@@ -996,15 +1057,35 @@ private static Map<String, String> getProperties(final VersionedComponent compon
996
1057
properties = processor .getProperties ();
997
1058
} else if (component instanceof VersionedControllerService controllerService ) {
998
1059
properties = controllerService .getProperties ();
999
- } else if (component instanceof VersionedReportingTask reportingTask ) {
1000
- properties = reportingTask .getProperties ();
1001
1060
} else {
1002
1061
properties = Collections .emptyMap ();
1003
1062
}
1004
1063
1005
1064
return properties == null ? Collections .emptyMap () : properties ;
1006
1065
}
1007
1066
1067
+ private static boolean isControllerServiceProperty (final FlowDifference difference , final FlowManager flowManager ) {
1068
+ final Optional <String > fieldNameOptional = difference .getFieldName ();
1069
+ if (fieldNameOptional .isEmpty ()) {
1070
+ return false ;
1071
+ }
1072
+
1073
+ final String propertyName = fieldNameOptional .get ();
1074
+ final Optional <PropertyDescriptor > componentDescriptor = getComponentPropertyDescriptor (flowManager , difference , propertyName );
1075
+ if (componentDescriptor .isPresent ()) {
1076
+ final PropertyDescriptor descriptor = componentDescriptor .get ();
1077
+ return !descriptor .isDynamic () && descriptor .getControllerServiceDefinition () != null ;
1078
+ }
1079
+
1080
+ final Optional <VersionedPropertyDescriptor > versionedDescriptor = getVersionedPropertyDescriptor (difference , false );
1081
+ if (versionedDescriptor .isPresent ()) {
1082
+ final VersionedPropertyDescriptor descriptor = versionedDescriptor .get ();
1083
+ return Boolean .TRUE .equals (descriptor .getIdentifiesControllerService ());
1084
+ }
1085
+
1086
+ return false ;
1087
+ }
1088
+
1008
1089
private static boolean valuesMatch (final Optional <String > first , final Optional <String > second ) {
1009
1090
return first .isPresent () && second .isPresent () && first .get ().equals (second .get ());
1010
1091
}
0 commit comments