[
https://issues.apache.org/jira/browse/NIFI-16440?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Xinyu Wang reassigned NIFI-16440:
---------------------------------
Assignee: Xinyu Wang
> Provided Parameters stay empty after restart once a failed Parameter Provider
> fetch has dropped their value from flow.json
> --------------------------------------------------------------------------------------------------------------------------
>
> Key: NIFI-16440
> URL: https://issues.apache.org/jira/browse/NIFI-16440
> Project: Apache NiFi
> Issue Type: Bug
> Components: Core Framework
> Affects Versions: 2.0.0, 2.12.0
> Reporter: Xinyu Wang
> Assignee: Xinyu Wang
> Priority: Major
> Time Spent: 10m
> Remaining Estimate: 0h
>
> h3. Problem
> NIFI-13560 (first released in 2.0.0) stopped persisting values fetched from a
> Parameter Provider. The flow configuration only keeps a reference
> ({{provided:parameter}}) and NiFi fetches the values again when it starts. If
> the Parameter Provider cannot be reached during that startup fetch, the
> reference is lost and the Parameters cannot recover on later restarts, even
> after the provider is healthy again.
> h3. Steps to reproduce
> # Configure a Parameter Provider and apply its Parameter Group so that a
> Parameter Context is bound to it. All Parameters have values.
> # Make the provider unreachable and restart NiFi. The startup fetch fails,
> {{Fetched Parameters [0]}} is logged, and every provided Parameter is empty.
> This part is expected.
> # Make the provider reachable again.
> # Restart NiFi, as many times as you like.
> h3. Actual behavior
> On every restart in step 4 the provider returns all Parameters ({{Fetched
> Parameters [4]}}), but every Parameter stays empty. The only way back is
> *Fetch Parameters* followed by *Apply Changes*.
> In flow.json the provided Parameters were serialized as
> {code}{"name":"key1","sensitive":false,"provided":true,"value":"provided:parameter"}{code}
> before step 2, and after step 2 they have *no {{value}} field at all*:
> {code}{"name":"key1","sensitive":false,"provided":true}{code}
> h3. Expected behavior
> Once the provider is reachable again, the next restart fetches the values and
> the Parameters are populated. A failed fetch should not remove the reference
> to the provider from the flow configuration.
> h3. Root cause
> Two null checks run before the provided check:
> # {{StandardParameterValueMapper.getMapped}} evaluates {{value == null}}
> before {{parameter.isProvided()}} (added in NIFI-13577 to avoid an NPE in the
> sensitive value encryptor). After a failed fetch the Parameter value is null,
> so the mapper returns null and the {{value}} field is omitted when flow.json
> is written.
> # {{VersionedFlowSynchronizer}} (the method that builds the Parameter map
> from the serialized Parameter Context) evaluates {{rawValue == null}} before
> the provided check. A provided Parameter without a stored value is set to
> null without looking at the values fetched from the provider.
> The failed fetch itself is only logged ({{Fetching Parameters for Group [...]
> from Provider [...] failed}}), then each provided Parameter logs {{Provided
> Parameter [x] not found}} and gets a null value. This happens for any
> provider whose {{fetchParameters}} throws, for example when the external
> service is unavailable during startup.
> h3. Proposed fix
> Evaluate {{isProvided()}} first in both places:
> * {{StandardParameterValueMapper.getMapped}}: return {{provided:parameter}}
> for provided Parameters even when the value is null.
> * {{VersionedFlowSynchronizer}}: for provided Parameters always use the value
> from the provider, regardless of the stored value.
> With this change the flow configuration keeps {{provided:parameter}} through
> a failed fetch, and the Parameters recover on the next restart after the
> provider is back (verified on 2.12.0, see below). Non-provided Parameters are
> not affected.
> h3. Verification
> Tested on stock {{apache/nifi}} images, standalone, with a Parameter Provider
> that throws {{IOException}} when its backend is down. The "without fix"
> column was reproduced on both 2.0.0 and 2.12.0 with identical results; the
> "with fix" column was tested on 2.12.0:
> || Scenario || Without fix || With fix ||
> | provider down, restart | Parameters empty, {{value}} dropped from flow.json
> | Parameters empty, {{provided:parameter}} kept in flow.json |
> | provider up again, restart (repeat 3 times) | Parameters stay empty every
> time | Parameters populated after one restart |
> | flow.json already missing {{value}} | stays empty | populated after one
> restart |
> h3. Notes
> * Existing unit test {{TestStandardParameterValueMapper}} covers a null value
> for a non-provided Parameter only; a provided Parameter with a null value is
> not covered.
> * Related: NIFI-13560 (design), NIFI-13577 (null handling in the mapper),
> NIFI-13688 (startup ordering of provider validation).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)