Repository navigation
Allow MetaInject to run when all input streams are empty - #9078
Merged
mattcasters merged 4 commits intoOct 24, 2026
Merged
mattcasters merged 4 commits into
mattcasters merged 4 commits into
Conversation
Introduce a ConditionStreamBehavior enum that replaces the legacy allowEmptyStreamOnExecution boolean. It adds a third ALWAYS mode so the injected template pipeline can run even when every input stream is empty (e.g. templates relying on constant mappings alone), while ALL_NON_EMPTY and AT_LEAST_ONE_NON_EMPTY preserve the previous false/true semantics. Add a general @OnUnknownDeserializationProperty callback honored by both the XML and JSON serializers, so legacy files still carrying the old allow_empty_stream_on_execution tag keep mapping correctly (Y/true to AT_LEAST_ONE_NON_EMPTY, N/false to ALL_NON_EMPTY), without writing it on new metadata. The helper returns instance-bound Consumer callbacks built from Class.getMethods(), so only public methods are discovered and a public override masks its parent. New files are serialized with only the condition_stream_behavior key. The dialog checkbox becomes a dropdown of the three modes, with en/fr/pt_BR labels, and the user/dev manuals document the option and the callback.
mattcasters
requested changes
Oct 21, 2026
Backward-compatible handling of the legacy ALLOW_EMPTY_STREAM_ON_EXECUTION injection key and allow_empty_stream_on_execution config tag after the move to ConditionStreamBehavior: remap the old injection key and translate Y/N/true/false to the enum code, apply the legacy tag only when the new enum is absent, fix unknown-value parsing in the JSON serializer, add missing i18n, and cover the legacy paths with parameterized tests.
Contributor
Author
|
@mattcasters tried to address all feedbacks and increase test coverage, do you mind having another look 🙏 ? |
mattcasters
requested changes
Oct 22, 2026
…very lookup site Address the round-2 review feedback on PR apache#9078: the legacy ALLOW_EMPTY_STREAM_ON_EXECUTION injection key is now normalized to CONDITION_STREAM_BEHAVIOR everywhere the mapping is read, not only during the injection itself. - collectDataForOneMapping resolves the key up front so lookupGroupKey and HopMetadataInjector.isTopLevelInjectionKey see the normalized key; a legacy mapping stored with target_detail=Y is no longer logged as TargetKeyNotFound and is injected under CONDITION_STREAM_BEHAVIOR. - getUnavailableTargetKeys checks the resolved key, so the dialog no longer offers to delete a legacy mapping that would actually run. - MetaInjectDialog.findMappingForTargetKey normalizes both keys so the source of a legacy mapping stays visible in the Inject Metadata tree. - resolveInjectionKey is widened to protected static so the dialog (same package) and subclasses can reuse it while staying out of the public API. Docs: the @OnUnknownDeserializationProperty example in the dev manual now shows the conditionStreamBehaviorSet guard so the legacy boolean cannot override an explicit condition_stream_behavior (current enum wins when both tags are present). Tests: add coverage for getUnavailableTargetKeys keeping a legacy-key mapping, and for the target_detail=Y scalar path injecting the enum code.
Contributor
Author
|
Updated the PR with review feedbacks |
mattcasters
requested changes
Oct 24, 2026
…avior change - ConditionStreamBehavior.isLegacyBoolean now compares with equalsIgnoreCase instead of default-locale toLowerCase, so an uppercase legacy TRUE still maps to AT_LEAST_ONE_NON_EMPTY even under a Turkish (or similar) JVM locale; the legacy key constant-injection test gains a mixed-case TRUE case. - MetaInjectDialog.enterMapping builds its MappingTarget with the normalized target key (new package-private resolveTargetAttributeKey, delegating to MetaInject.resolveInjectionKey) instead of the raw saved key, so a mapping still stored as ALLOW_EMPTY_STREAM_ON_EXECUTION is pre-selected in the mapping dialog and survives a confirm instead of being dropped. - The condition-stream-behavior CCombo is now SWT.READ_ONLY so only the enum descriptions can be selected; a typo or cleared field can no longer silently fall back to ALL_NON_EMPTY. - Test/dialog javadocs no longer narrate the PR review history; they state the behavior under test, and the resolveInjectionKey javadoc lists every lookup site (now including the enter-mapping target row).
mattcasters
approved these changes
Oct 24, 2026
Contributor
|
Ran all the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #9077
Problem
The MetaInject (ETL Metadata Injection) transform had a single
allowEmptyStreamOnExecutionboolean that only distinguished whether every stream must have data (false) or at least one must (true). There was no way to run the injected template pipeline when all input streams are empty, even though templates relying on constant mappings alone are valid.Solution
Replace the boolean with a three-state
ConditionStreamBehaviorenum:ALL_NON_EMPTY-- run only when every stream has data (legacyfalse/N)AT_LEAST_ONE_NON_EMPTY-- run when at least one stream has data (legacytrue/Y)ALWAYS-- new: run even when every input stream is emptyBackward compatibility
The old
allow_empty_stream_on_executionfield is removed from new serialized metadata (new files carry onlycondition_stream_behavior), but old files still load and map deterministically:Y/true->AT_LEAST_ONE_NON_EMPTY,N/false->ALL_NON_EMPTY, missing (pre-legacy) ->ALL_NON_EMPTY. An explicitYis never confused with a missing tag.This is implemented through a new, general core mechanism: the
@OnUnknownDeserializationPropertyannotation, honored by both the XML and JSON serializers, lets any annotated metadata class translate a legacy/renamed key into a current field during deserialization.ReflectionUtilreturns instance-boundConsumer<UnknownProperty>callbacks built fromClass.getMethods(), so:(UnknownProperty)fails fast withIllegalArgumentException,with the discovery result cached per class.
UI & docs
en/fr/pt_BRlabels.Tests
UnknownDeserializationPropertyTest(8) -- XML + JSON firing, no-fire for annotated keys, multiple callbacks, override-masking, invalid signature ->IllegalArgumentException, non-public exclusion.MetaInjectMetaTest(7) +MetaInjectTest(13) -- new-code round-trip, legacyY/N, missing -> default, "new writes only enum" check, and theshouldSkipExecutiongate matrix.Verification
mvn -T1C clean testonmetainject: 20 tests, 0 failuresConfigFile.java:54)