*ListenDynamicPropertyChange
> On Jan 8, 2021, at 12:42, Otto Fowler <[email protected]> wrote:
>
> So you would be implementing ListDynamicPropertyChange kind of.
>
>
>> On Jan 8, 2021, at 12:41, Otto Fowler <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> What are the attributes of the processor?
>> Do you have :
>>
>> @InputRequirement(InputRequirement.Requirement.INPUT_FORBIDDEN)
>> or anything?
>>
>> You should take a look at the Listen** processors.
>> They do not have any inputs etc, and run processing queued input from a
>> background thread.
>> You can have on modified queue a change and then have trigger process the
>> queue of changes.
>>
>>
>>
>>> On Jan 8, 2021, at 11:04, Russell Bateman <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>> I only put the code I want to execute in onTrigger(), I suspected it would
>>> not fire there. I know that this isn't what processors do. Configuration is
>>> a messy problem to solve when your downstreamers want it made easy. This is
>>> supposed to be a solution that allows them to remain in the NiFi UI and not
>>> have to run off doing harder things to configure. I could put what I'm
>>> doing in /HumanReadables/ into a real, running processor, but then, I would
>>> kind of have to add them to several processors and I wanted to avoid the
>>> confusion that created.
>>>
>>> Here's the code. Thanks.
>>>
>>> import com.windofkeltia.constants.HumanReadableMappings;
>>>
>>> ...
>>>
>>> @TriggerWhenEmpty
>>> @SideEffectFree
>>> @CapabilityDescription( "Dynamic properties can be created to specify (or
>>> add to) static configuration"
>>> + " of key-value substitution pairs. See additional
>>> details." )
>>> public class HumanReadables extends AbstractProcessor
>>> {
>>> @Override
>>> public void onTrigger( final ProcessContext context, final ProcessSession
>>> session ) throws ProcessException
>>> {
>>> getLogger().info( "inside onTrigger()..." );
>>>
>>> for( Map.Entry< PropertyDescriptor, String > entry :
>>> context.getProperties().entrySet() )
>>> {
>>> PropertyDescriptor property = entry.getKey();
>>>
>>> // do work here--maybe pre-wipe all key-value pairs if we're just
>>> going to recreate them?
>>> final String PROPERTY_NAME = property.getName();
>>> final String PROPERTY_VALUE = entry.getValue();
>>>
>>> logger.trace( "Processing configurable mappings titled \"" +
>>> PROPERTY_NAME + "\"" );
>>>
>>> try
>>> {
>>> harvestDynamicPropertyMappings( PROPERTY_VALUE );
>>> }
>>> catch( Exception e )
>>> {
>>> getLogger().debug( e.getMessage() );
>>> }
>>> }
>>> }
>>>
>>> protected static void harvestDynamicPropertyMappings( final String
>>> PROPERTY_VALUE )
>>> {
>>> final String[] LINES = PROPERTY_VALUE.split( "\n" );
>>> int lineNumber = 0;
>>>
>>> if( LINES.length < 1 )
>>> return;
>>>
>>> final String WHICH_LIST = LINES[ 0 ];
>>>
>>> for( final String VALUE_LINE : LINES )
>>> {
>>> char delimiter = VALUE_LINE.charAt( 0 );
>>> int position = VALUE_LINE.indexOf( delimiter, 1 );
>>> String key, value;
>>>
>>> key = ( position < 0 ) ? VALUE_LINE.substring( 1 ) :
>>> VALUE_LINE.substring( 1, position ).trim();
>>> value = ( position > 0 ) ? VALUE_LINE.substring( position + 1
>>> ).trim() : "";
>>>
>>> HumanReadableMappings.add( key, value );
>>> }
>>> }
>>>
>>> @Override
>>> protected PropertyDescriptor getSupportedDynamicPropertyDescriptor( final
>>> String propertyDescriptorName )
>>> {
>>> return new PropertyDescriptor.Builder()
>>> .required( false )
>>> .name( propertyDescriptorName )
>>> .addValidator(
>>> StandardValidators.NON_EMPTY_VALIDATOR )
>>> // or .addValidator( Validator.VALID ) if
>>> you do not wish it validated!
>>> .dynamic( true )
>>> .build();
>>> }
>>>
>>> private volatile Set< String > dynamicPropertyNames = new HashSet<>();
>>>
>>> @Override
>>> public void onPropertyModified( final PropertyDescriptor descriptor,
>>> final String oldValue, final String newValue )
>>> {
>>> getLogger().info( oldValue + " -> " + newValue );
>>>
>>> final Set< String > newDynamicPropertyNames = new HashSet<>(
>>> dynamicPropertyNames );
>>>
>>> if( isNull( newValue ) )
>>> newDynamicPropertyNames.remove( descriptor.getName() );
>>> else if( isNull( oldValue ) && descriptor.isDynamic() )
>>> newDynamicPropertyNames.add( descriptor.getName() );
>>>
>>> dynamicPropertyNames = Collections.unmodifiableSet(
>>> newDynamicPropertyNames );
>>>
>>> final Set< String > allDynamicProperties = dynamicPropertyNames;
>>> }
>>>
>>> @OnScheduled public void processProperties( final ProcessContext context )
>>> {
>>> for( Map.Entry< PropertyDescriptor, String > entry :
>>> context.getProperties().entrySet() )
>>> {
>>> PropertyDescriptor descriptor = entry.getKey();
>>>
>>> if( descriptor.isDynamic() )
>>> getLogger().debug( "Dynamic property named:\n " +
>>> descriptor.getName()
>>> + ", value: " + entry.getValue().replaceAll(
>>> "\n", " + " ) );
>>> }
>>> }
>>>
>>> protected static final String DEFAULT_MAPPING_VALUE = ""
>>> + "|http://loinc.org <http://loinc.org/> |LOINC\n"
>>> + "|http://snomed.info/sct <http://snomed.info/sct> |SNOMED\n"
>>> + "|http://www.ama-assn.org/go/cpt <http://www.ama-assn.org/go/cpt>
>>> |CPT\n"
>>> + "|http://aapc.org <http://aapc.org/>
>>> |CPT\n"
>>> + "|http://www.nlm.nih.gov/research/umls/rxnorm
>>> <http://www.nlm.nih.gov/research/umls/rxnorm> |RxNorm\n"
>>> + "|http://hl7.org/fhir/sid/ndc <http://hl7.org/fhir/sid/ndc>
>>> |NDC\n"
>>> + "|http://hl7.org/fhir/sid/icd-9-cm <http://hl7.org/fhir/sid/icd-9-cm>
>>> |ICD-9\n"
>>> + "|http://hl7.org/fhir/sid/icd-10 <http://hl7.org/fhir/sid/icd-10>
>>> |ICD-10\n";
>>>
>>> public static final PropertyDescriptor DEFAULT_MAPPINGS = new
>>> PropertyDescriptor.Builder()
>>> .name( "default mappings" )
>>> .displayName( "Default mappings" )
>>> .required( false )
>>> .expressionLanguageSupported( ExpressionLanguageScope.NONE )
>>> .defaultValue( DEFAULT_MAPPING_VALUE )
>>> .addValidator( Validator.VALID )
>>> .description( "These default mappings are already set up, but can be
>>> changed. To erase completely,"
>>> + " merely clear the value of this property and ignore it
>>> in favor of creating and"
>>> + " maintaining one or more of your own dynamic
>>> properties.")
>>> .build();
>>>
>>> private List< PropertyDescriptor > properties;
>>>
>>> @Override
>>> public void init( final ProcessorInitializationContext context )
>>> {
>>> List< PropertyDescriptor > properties = new ArrayList<>();
>>> properties.add( DEFAULT_MAPPINGS );
>>> this.properties = Collections.unmodifiableList( properties );
>>> }
>>>
>>> @Override public List< PropertyDescriptor >
>>> getSupportedPropertyDescriptors() { return properties; }
>>> }
>>>
>>
>