Skip to content

feat(graph): resolve Java string-constant refs in producer/client topic args #378

Description

@HumanBean17

Context

Producer (and HTTP client) topics/destinations that reference a Java string constant — kafkaTemplate.send(ChatTopics.COMPLIANCE_REVIEW, …), restTemplate.exchange(Endpoints.X, …) — are indexed as the unresolved expression text ("ChatTopics.COMPLIANCE_REVIEW") instead of the constant's literal value ("banking.chat.compliance.review"). Any topic/endpoint-keyed lookup then misses them.

Concrete failure: jrag overview banking.chat.compliance.review returns the consumer (ComplianceReviewListener, whose @CodebaseAsyncRoute(topic="…") annotation supplies the literal) but not the producer (FollowUpKafkaPublisher#publishComplianceReview), because the producer's stored topic is ChatTopics.COMPLIANCE_REVIEW.

Why it was deferred

Surfaced while fixing test_overview_topic_lists_producers_and_consumers (red since PR-JRAG-4) on feat/cli. The id-free CLI branch patched the symptom by adding a brownfield @CodebaseProducer(topic="banking.chat.compliance.review") annotation to the one fixture producer (tests/bank-chat-system/.../FollowUpKafkaPublisher.java), mirroring the existing @CodebaseProducer on publishIncoming. The underlying engine gap remains.

Root cause

  • ast_java.py:1145 and :1273-1274 classify Class.FIELD string args as "constant_ref" (confidence 0.7, unresolved) and never look up the value.
  • public static final String field declarations are not indexed with their initializer value — ChatTopics constant fields do not appear as symbols at all (verified: only the class + constructor are indexed).
  • graph_enrich.py:821 also falls back to constant_ref for route-path hints.
  • No constant-resolution infrastructure exists (no const-value capture, no Class.FIELD → value map).

What is needed to implement

  1. Parser (ast_java.py): capture literal initializer values for public static final String fields (extend the field-decl path).
  2. Builder (build_ast_graph.py, pass4 producers/clients): build a {SimpleClass.FIELD → value} and {FQN.FIELD → value} map; resolve constant_ref topic/destination args through it before storing.
  3. Enrichment (graph_enrich.py): apply the same resolution in the route-path canonical ladder (:814-821).
  4. Tests: add coverage in tests/test_ast_*.py / test_bank_chat_brownfield_integration.py; once it lands, the @CodebaseProducer workaround on publishComplianceReview can stay (harmless) or be removed to exercise the resolution path.

Impact

Without it, producers/clients that reference topic/endpoint constants do not link to their topic/endpoint, so jrag overview <topic>, jrag topics, cross-service ASYNC_CALLS/HTTP_CALLS chains, and trace-request-flow miss them unless a brownfield annotation manually supplies the literal.

Workaround today

@CodebaseProducer(topic=…) / @CodebaseAsyncRoute(topic=…) brownfield annotations supply the resolved literal at index time (graph_enrich.py honors them).

Related

  • Test: tests/test_jrag_orientation.py:157 (test_overview_topic_lists_producers_and_consumers)
  • Fixture producer: tests/bank-chat-system/chat-core/chat-engine/src/main/java/com/bank/chat/engine/kafka/FollowUpKafkaPublisher.java
  • Branch: feat/cli

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions