shashank created CAMEL-25050:
--------------------------------

             Summary: variableReceive into a route: or group: variable stores 
the header variables under a route (group) with the id "header", so 
route:header:resp.status does not find them
                 Key: CAMEL-25050
                 URL: https://issues.apache.org/jira/browse/CAMEL-25050
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: shashank


With {{variableReceive}} ({{toV}}, {{enrich}}, {{pollEnrich}}, {{toD}}, 
{{fromV}}) the received body is stored in the variable and each received header 
as {{header:NAME.KEY}} 
({{ExchangeHelper.setVariableFromMessageBodyAndHeaders}}). For a route or group 
variable, NAME is the resolved repository name ({{rs:resp}} for {{route:resp}} 
in route {{rs}}, {{myGroup:resp}} for {{group:myGroup:resp}}), so the header 
key becomes {{header:rs:resp.status}}. {{RouteVariableRepository}} and 
{{GroupVariableRepository}} take the text before the first colon as the route 
(group) id. The header variables therefore end up in a route (group) whose id 
is {{header}}, not in the route or group of the variable:

{noformat}
toV("direct:svc", null, "route:resp") in route rs, reply header status=200:
  route repository names: [header:rs:resp.status, rs:resp]

toV("direct:svc", null, "group:myGroup:resp"):
  group repository names: [header:myGroup:resp.status, myGroup:resp]
{noformat}

Consequences:
* The body is read with {{route:resp}}, but the header can only be read with 
the internal key {{route:header:rs:resp.status}}. The names a user would try 
return null:
{noformat}
route rs, after toV into route:resp (reply header status=200)
  getVariable("route:resp")                   Bye Hello
  getVariable("route:header:rs:resp.status")  200
  getVariable("route:header:resp.status")     null
  getVariable("route:rs:header:resp.status")  null
  getVariable("header:route:resp.status")     null

after toV into group:myGroup:resp
  getVariable("group:header:myGroup:resp.status")  200
  getVariable("group:myGroup:header:resp.status")  null
  getVariable("header:group:myGroup:resp.status")  null
{noformat}
{{route:header:resp.status}} is resolved as variable {{resp.status}} of a route 
named {{header}}: {{ExchangeHelper.resolveVariableRepositoryName}} only adds 
the current route id when the name has no colon.
* The exchange repository returns all header variables of a variable as a map 
for {{header:resp}} (a map with status=200) and removes them all for 
{{removeVariable("header:resp")}}. The route and group repositories have no 
such lookup: {{route:header:rs:resp}} returns null.
* Removing a route removes its variables ({{DefaultVariableRepositoryFactory}} 
calls {{removeVariable(routeId + ":*")}}), but not the header variables of its 
route variables, because they live under the id {{header}}. After 
{{removeRoute("rs")}} the route repository still has {{header:rs:resp.status}}.
* {{GroupVariableRepository.getGroupIds()}} returns the keys of its group map, 
so it includes a group {{header}} that no route uses.
* The header variables of all routes (all groups) share one map, so the removal 
of the old header variables added by CAMEL-25035 scans that shared map instead 
of the map of the variable's route or group.

Reproduced on 4.23.0-SNAPSHOT (branch of PR #26910; the naming is the same on 
main, the PR does not change it) with a {{ContextTestSupport}} test that reads 
the names above after {{toV}}.

*Proposed fix* (a behaviour change, so it needs a decision on the naming): 
store the header variables of a route or group variable in the map of that 
route or group, with the key {{header:resp.KEY}} under the id {{rs}}, that is 
the repository name {{rs:header:resp.status}}. Then:
* resolve {{route:header:resp.status}} to the current route like 
{{route:resp}}, and accept {{route:rs:header:resp.status}} with an explicit 
route id; the same for groups with {{group:myGroup:header:resp.status}};
* removing a route removes the header variables of its variables too;
* the removal in {{setVariableFromMessageBodyAndHeaders}} only scans the map of 
the variable's route or group;
* optionally support the {{header:resp}} map lookup and removal in the route 
and group repositories, as the exchange repository does.

Compatibility: {{route:header:rs:resp.status}} (the only name that works today) 
would no longer find the header, and {{route:header:x}} would no longer mean 
variable {{x}} of a route with the id {{header}}. The alternative is to keep 
the storage and document {{route:header:ROUTEID:NAME.KEY}} and 
{{group:header:GROUPID:NAME.KEY}} as the names to use in {{variables.adoc}}.

Found while fixing CAMEL-25035 (PR #26910), where the tests read the route and 
group header variables with {{route:header:rs:resp.status}} and 
{{group:header:myGroup:resp.status}}.

_Filed with Claude Code on behalf of allthingssecurity._




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

Reply via email to