Skip to content

Port AOSS propagation race fix and LDD load hardening from registry-common#291#91

Open
jordanpadams wants to merge 1 commit into
mainfrom
issues/81-aoss-ldd-propagation-race
Open

Port AOSS propagation race fix and LDD load hardening from registry-common#291#91
jordanpadams wants to merge 1 commit into
mainfrom
issues/81-aoss-ldd-propagation-race

Conversation

@jordanpadams

Copy link
Copy Markdown
Member

🗒️ Summary

Sister PR to NASA-PDS/registry-common#291 — ports all applicable fixes to the registry-loader common/ module. The duplication is intentional while registry-common is being deprecated.

Changes ported

AOSS propagation race fixes (#81)

  • ConnectionFactory: add isServerless() default method
  • UseOpensearchSDK2: add isServerless() override
  • Request: add MGet.setRefresh(boolean) and Search.buildListLddsNoCache(String)
  • MGetImpl (aws), GetImpl (es), SearchImpl (aws/es): implement new interface methods
  • DataDictionaryDao: add getLddInfoNoCache(); add getDataTypes(ids, forceRefresh) overload while preserving the structured-metadata id-mapping logic unique to registry-loader
  • JsonLddLoader: in-memory loadedThisRun cache to avoid redundant AOSS queries; SearchIndexWait for sentinel and mget visibility with 30s timeout; guard against zero-field LDD writing the LDD_Info sentinel; loadOnly() demoted to package-private returning boolean; CaaCallback now tracks firstFieldId
  • SchemaUpdater: stores conFact; wraps getDataTypes in SearchIndexWait.untilVisible only on AOSS deployments; improved DataTypeNotFoundException error message; debug log for already-loaded LDD
  • SearchIndexWait: new package-private polling utility class

Bug fixes

  • AutogenExtractor: skip empty container elements (e.g. <geom:Illumination_Geometry/>) that have no text content — these caused DataTypeNotFoundException during schema resolution (NASA-PDS/registry-common#293)
  • FileDownloader: include URL in retry error message (was anonymous); demote per-file download log to DEBUG

What was NOT ported

  • ClassAttrAssociationParser throw-on-missing-association: registry-loader intentionally warns and continues here to support structured metadata LDD formats where the association format may differ

Test differences

TestAutogenExtractor uses . (dot) as the field separator instead of / (slash) because registry-loader uses MetaConstants.ATTR_SEPARATOR = "." for structured metadata support.

⚙️ Test data and/or report

  • TestSearchIndexWait: 10 unit tests — all pass
  • TestAutogenExtractor: 2 regression tests (real New Horizons MVIC label) — all pass
  • Full build: mvn clean install — BUILD SUCCESS (26 tests, 0 failures)

♻️ Related issues

Fixes #81
Sister PR: NASA-PDS/registry-common#291

🤓 Reviewer checklist

  • Documentation: Changes are documented in commit message and PR body
  • Security: No sensitive information exposed; exception handling follows project conventions
  • Testing: Unit tests cover the core polling logic and regression cases
  • Maintenance: Code follows existing patterns; no unnecessary abstractions added

🤖 Generated with Claude Code

…ommon#291

Sister PR to NASA-PDS/registry-common#291. Applies all applicable changes to
the registry-loader common/ module. Changes where the registry-loader differs
from registry-common (structured metadata support, dot-separated field paths)
are preserved.

Changes ported:
- ConnectionFactory: add isServerless() default method (returns false)
- UseOpensearchSDK2: add isServerless() override
- Request: add MGet.setRefresh(boolean) and Search.buildListLddsNoCache(String)
- MGetImpl (aws): implement setRefresh() via craftsman.refresh()
- GetImpl (es): implement setRefresh() as no-op (SDK1 ES path)
- SearchImpl (aws): implement buildListLddsNoCache() with requestCache=false
- SearchImpl (es): implement buildListLddsNoCache() (cache disabled at index level)
- DataDictionaryDao: add getLddInfoNoCache(), merge getDataTypesWithRefresh() into
  getDataTypes(ids, forceRefresh) overload; preserves structured-metadata id mapping
- JsonLddLoader: in-memory loadedThisRun cache; SearchIndexWait for sentinel and
  mget visibility; guard zero-field LDD sentinel; loadOnly() package-private returning
  boolean; CaaCallback tracks firstFieldId
- SchemaUpdater: store conFact; wrap getDataTypes in SearchIndexWait.untilVisible
  on AOSS; improved DataTypeNotFoundException error message; debug log for already-loaded
- SearchIndexWait: new package-private polling utility (ported from registry-common)
- AutogenExtractor: skip empty container elements to prevent DataTypeNotFoundException
- FileDownloader: include URL in retry error message; demote downloadOnce log to debug
- TestSearchIndexWait: 10 unit tests
- TestAutogenExtractor: 2 regression tests (field paths use '.' separator per
  registry-loader structured metadata convention)

Not ported:
- ClassAttrAssociationParser throw-on-missing-association: registry-loader warns
  and continues to support structured metadata LDD formats

Fixes #81

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jordanpadams jordanpadams added the bug Something isn't working label Jul 2, 2026
@jordanpadams jordanpadams requested a review from a team as a code owner July 2, 2026 22:36
@jordanpadams jordanpadams added the bug Something isn't working label Jul 2, 2026
@sonarqubecloud

sonarqubecloud Bot commented Jul 2, 2026

Copy link
Copy Markdown

@nutjob4life nutjob4life left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having déjà vu all over again 😆

I did find 2½ issues this time around; see the interspersed comments and if they can be approached or explained, we're good to go.

Comment on lines 51 to 53
public Get setIndex(String index) {
this.setIndex(index);
return this;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that these three lines were not part of the PR but isn't this just a stack overflow waiting to happen? It's a recursive call to itself with no base case.

// Wait until the LDD_Info sentinel is visible via search (confirms bulk load completed).
LddVersions info = SearchIndexWait.untilReady(SearchIndexWait.DEFAULT_WAIT_SECONDS,
() -> { try { return dao.getLddInfoNoCache(namespace); } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException(e); } },
v -> !v.isEmpty(), log, "LDD sentinel for namespace " + namespace);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This proves only that some LDD info exists for the namespace. If the namespace already had prior LDDs loaded, this can pass immediately before the newly loaded lddFileName is visible. That undercuts the AOSS race fix.

Maybe?

v -> v.files.contains(lddFileName)

or otherwise confirm the newly loaded LDD version/date.

// no text content and no corresponding LDD attribute entry, so indexing them as
// an empty-string field would later cause DataTypeNotFoundException during schema
// resolution. See https://github.com/NASA-PDS/registry-common/issues/293.
if(fieldValue.isEmpty()) return;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, this skips more than just empty container elements like

<empty_container/>

but will also skip empty text leaf nodes like

<non_empty_but_skipped_container>    </non_empty_but_skipped_container>

The comment says it only skips the former.

But maybe that's the correct behavior! If so, the comment should be updated. If not, then the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AOSS propagation race: LDD re-downloaded and fields fail to resolve immediately after bulk load into -dd index

2 participants