From e9c2535df73ab72d7a20f9dc2f27ae2bd6ad02e5 Mon Sep 17 00:00:00 2001 From: Mark Payne Date: Wed, 12 Aug 2015 10:09:02 -0400 Subject: [PATCH] NIFI-843: Ensure that a new HashMap is used when populating the propertyMap member variable for thread safety --- .../processors/standard/RouteOnAttribute.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/RouteOnAttribute.java b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/RouteOnAttribute.java index 0d113ced59..7055a8a9d2 100644 --- a/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/RouteOnAttribute.java +++ b/nifi/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/RouteOnAttribute.java @@ -34,7 +34,6 @@ import org.apache.nifi.annotation.behavior.SupportsBatching; import org.apache.nifi.annotation.documentation.CapabilityDescription; import org.apache.nifi.annotation.documentation.Tags; import org.apache.nifi.annotation.lifecycle.OnScheduled; -import org.apache.nifi.annotation.lifecycle.OnStopped; import org.apache.nifi.components.AllowableValue; import org.apache.nifi.components.PropertyDescriptor; import org.apache.nifi.components.PropertyValue; @@ -106,8 +105,7 @@ public class RouteOnAttribute extends AbstractProcessor { private volatile Set dynamicPropertyNames = new HashSet<>(); /** - * Cache of dynamic properties set during {@link #onScheduled(ProcessContext)} and - * cleared during {@link #onStopped(ProcessContext)} for quick access in + * Cache of dynamic properties set during {@link #onScheduled(ProcessContext)} for quick access in * {@link #onTrigger(ProcessContext, ProcessSession)} */ private volatile Map propertyMap = new HashMap<>(); @@ -182,20 +180,18 @@ public class RouteOnAttribute extends AbstractProcessor { */ @OnScheduled public void onScheduled(final ProcessContext context) { + final Map newPropertyMap = new HashMap<>(); for (final PropertyDescriptor descriptor : context.getProperties().keySet()) { if (!descriptor.isDynamic()) { continue; } getLogger().debug("Adding new dynamic property: {}", new Object[]{descriptor}); - propertyMap.put(new Relationship.Builder().name(descriptor.getName()).build(), context.getProperty(descriptor)); + newPropertyMap.put(new Relationship.Builder().name(descriptor.getName()).build(), context.getProperty(descriptor)); } + + this.propertyMap = newPropertyMap; } - @OnStopped - public void onStopped() { - getLogger().debug("Clearing propertyMap"); - propertyMap.clear(); - } @Override public void onTrigger(final ProcessContext context, final ProcessSession session) { @@ -206,8 +202,9 @@ public class RouteOnAttribute extends AbstractProcessor { final ProcessorLog logger = getLogger(); + final Map propMap = this.propertyMap; final Set matchingRelationships = new HashSet<>(); - for (final Map.Entry entry : propertyMap.entrySet()) { + for (final Map.Entry entry : propMap.entrySet()) { final PropertyValue value = entry.getValue(); final boolean matches = value.evaluateAttributeExpressions(flowFile).asBoolean(); @@ -219,7 +216,7 @@ public class RouteOnAttribute extends AbstractProcessor { final Set destinationRelationships = new HashSet<>(); switch (context.getProperty(ROUTE_STRATEGY).getValue()) { case routeAllMatchValue: - if (matchingRelationships.size() == propertyMap.size()) { + if (matchingRelationships.size() == propMap.size()) { destinationRelationships.add(REL_MATCH); } else { destinationRelationships.add(REL_NO_MATCH);