Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Envoy Json-To-Metadata using Array to match json body #38062

Open
rlanhellas opened this issue Jan 16, 2025 · 0 comments
Open

Envoy Json-To-Metadata using Array to match json body #38062

rlanhellas opened this issue Jan 16, 2025 · 0 comments
Labels
area/json enhancement Feature requests. Not bugs or questions.

Comments

@rlanhellas
Copy link

rlanhellas commented Jan 16, 2025

Title: Improvement to accept array match on Json-To-Metadata filter

Description:
I'm using the Json-To-Metadata filter and it works very well for JSON fields outside arrays. But Imagine the following structure:

{
 "data": {
    "regions": [
        {"name": "america"}
      ]
 }
}

How can I match using data.regions[0] where value equal to america ? Simple answer. I can't. Because the current filter is using node->getObject() (https://github.com/envoyproxy/envoy/blob/main/source/extensions/filters/http/json_to_metadata/filter.cc#L370), it never expects an array.

My suggestion would be to enable the support to array, at least for a specific position in array, we don't need to iterate over all array, just get an index and match the value. I implemented that solution locally and worked perfectly, so here is my idea:

absl::StatusOr<Json::ObjectSharedPtr> next_node_result;
const std::string keyword_array = "@array_";
const std::int16_t keyword_array_sizeof = 7;
for (unsigned long i = 0; i < keys.size() - 1; i++) {
  if (keys[i].find(keyword_array) != std::string::nops){
    next_node_result = node->getObjectArray(keys[i].substr(keyword_array_sizeof))[0];
  }else{
     next_node_result = node->getObject(keys[i]);
  }
}

A bit explanation about my idea. If the selector has @array_ it means we want to use array and not just simple object. In that case we use the getObjectArray and not getObject. Now the selector would be data.@array_regions.

In this sample code I'm getting always the first item of array (index zero), but we should add it to selector as well, like this one: data.@array_3_regions, so we can pick up the correct item.

For me lookup through an array is very important and a requirement, so we can't use this filter without this. I have the code ready to open a PR but would like to hear you guys first and I can push my PR.

@rlanhellas rlanhellas added enhancement Feature requests. Not bugs or questions. triage Issue requires triage labels Jan 16, 2025
@jmarantz jmarantz added area/json and removed triage Issue requires triage labels Jan 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/json enhancement Feature requests. Not bugs or questions.
Projects
None yet
Development

No branches or pull requests

2 participants