So you would be implementing ListDynamicPropertyChange kind of.

> On Jan 8, 2021, at 12:41, Otto Fowler <[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; }
>> }
>> 
> 

Reply via email to