[ 
https://issues.apache.org/jira/browse/NIFI-16444?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Xinyu Wang updated NIFI-16444:
------------------------------
    Affects Version/s: 2.12.0

> Property migration creates a new Controller Service and overwrites a 
> parameter reference when the referenced parameter has no value
> -----------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: NIFI-16444
>                 URL: https://issues.apache.org/jira/browse/NIFI-16444
>             Project: Apache NiFi
>          Issue Type: Bug
>          Components: Core Framework
>    Affects Versions: 2.5.0, 2.12.0
>            Reporter: Xinyu Wang
>            Priority: Major
>
> When a processor property that identifies a Controller Service is set to a 
> parameter reference (for example {{#\{aws-cs\}}}) and the parameter has no 
> value at the time the flow is loaded, {{migrateProperties}} treats the 
> property as unset. Processors whose migration creates a default Controller 
> Service for an unset property then create one and overwrite the parameter 
> reference with the new service ID.
> The overwrite is written back to the flow, so the parameter reference is lost 
> permanently. Setting the parameter value afterwards and restarting does not 
> restore it.
> h3. Cause
> {{StandardPropertyConfiguration.isPropertySet()}} evaluates the effective 
> value:
> {code:java}
> public boolean isPropertySet(final String propertyName) {
>     // Use Effective Properties here because the value may be set to 
> #{MY_PARAM} but if parameter MY_PARAM is not set, the property should be 
> considered unset.
>     return effectiveProperties.get(propertyName) != null;
> }
> {code}
> {{AbstractAWSCredentialsProviderProcessor.migrateAuthenticationProperties()}} 
> (and the equivalent code in {{AbstractAwsProcessor}}) then does:
> {code:java}
> if (!config.isPropertySet(AWS_CREDENTIALS_PROVIDER_SERVICE)) {
>     ...
>     } else {
>         final String serviceId = 
> config.createControllerService(CREDENTIALS_SERVICE_CLASSNAME, Map.of(
>                 AUTH_SERVICE_ANONYMOUS_CREDENTIALS, "true"));
>         config.setProperty(AWS_CREDENTIALS_PROVIDER_SERVICE, serviceId);
>     }
> }
> {code}
> A property set to {{#\{param\}}} is configured by the user, so it should not 
> be treated as unset. The newly created service has no credentials, and 
> replaces the intended service.
> The same {{isPropertySet}} pattern guards {{createControllerService}} in 
> {{ProxyServiceMigration}}, {{SchemaRegistryService}}, 
> {{SchemaRegistryRecordSetWriter}} and {{PutElasticsearchRecord}}.
> h3. Steps to reproduce (NiFi 2.5.0)
> # Create a Parameter Context with parameter {{aws-cs}} whose value is the ID 
> of an existing AWSCredentialsProviderControllerService, and assign it to the 
> root group.
> # Add a FetchS3Object processor and set {{AWS Credentials Provider service}} 
> to {{#\{aws-cs\}}}.
> # Stop NiFi and remove the {{value}} field of parameter {{aws-cs}} from 
> {{flow.json.gz}} (this simulates the parameter having no value at startup, 
> for example a Parameter Provider that has not fetched yet).
> # Start NiFi.
> Expected: the property remains {{#\{aws-cs\}}}.
> Actual: a new AWSCredentialsProviderControllerService with 
> {{anonymous-credentials=true}} and no keys is created and the property is 
> replaced by its ID. The log contains:
> {noformat}
> o.a.n.m.StandardControllerServiceFactory Created 
> StandardControllerServiceNode[service=AWSCredentialsProviderService[id=...], 
> name=AWSCredentialsProviderControllerService, ...] as a step in the migration 
> of FetchS3Object[id=...]
> {noformat}
> With the parameter value present, restarting creates no new service. After 
> the failure, setting the parameter value and restarting again leaves the 
> processor pointing at the new service.
> h3. Proposed fix
> Do not change {{isPropertySet()}}, since other migrations rely on a parameter 
> without a value being treated as unset for plain properties. Instead, the 
> migration code should check whether a raw value exists for properties that 
> identify a Controller Service, for example:
> {code:java}
> if (config.getRawPropertyValue(AWS_CREDENTIALS_PROVIDER_SERVICE).isEmpty()) {
> {code}
> A one-line change of this kind in {{AbstractAWSCredentialsProviderProcessor}} 
> was verified on 2.5.0: with the parameter value removed, no service is 
> created and the property keeps {{#\{aws-cs\}}}; restoring the value and 
> restarting also keeps it. The other migration call sites listed above need 
> the same review.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to