AIML-362: Fix status filtering for vulnerability search #67
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.
Summary
This PR fixes status filtering for vulnerability search tools (
search_vulnerabilitiesandsearch_app_vulnerabilities) by properly passing thestatusfield to TeamServer's POST API. It also refactors session metadata filter parsing for type safety.Key changes:
statusfield toExtendedTraceFilterBody(the SDK'sTraceFilterBodylacks it)reported→Reported)sessionMetadataFiltersdirectly to domain type (eliminates@SuppressWarnings("unchecked"))Why
The vulnerability search tools accept a
statusesparameter (e.g.,Reported,Confirmed,Fixed), but this filter was never actually sent to TeamServer. The SDK'sTraceFilterBodyclass doesn't have astatusfield, so even though we parsed and validated the parameter, we weren't including it in the POST request body.Additionally, the
sessionMetadataFiltersparameter usedMap<String, Object>requiring unsafe casts at runtime. This is a code smell that indicates missing domain modeling.What Changed
1. Added
statusfield toExtendedTraceFilterBodyThe SDK's
TraceFilterBodyis missing thestatusfield that TeamServer's API supports. We extend it to add this field:2. Updated params classes to return
ExtendedTraceFilterBodyBoth
VulnerabilityFilterParams.toTraceFilterBody()andSearchAppVulnerabilitiesParams.toTraceFilterBody()now:ExtendedTraceFilterBodyinstead ofTraceFilterBodystatusfield from the parsed statuses3. Made status filtering case-insensitive
Users can now specify statuses in any case:
reported→ normalized toReportedCONFIRMED→ normalized toConfirmedfixed→ normalized toFixedThis was implemented by enhancing
StringListSpec.allowedValues()to automatically perform case-insensitive matching and normalization to canonical form.4. Removed unnecessary
withSessionFilters()factory methodThe old
ExtendedTraceFilterBody.withSessionFilters()method copied all fields from a sourceTraceFilterBodythen added session parameters. This was over-engineered - we can simply:ExtendedTraceFilterBodydirectly in the params classThis removes ~50 lines of code and makes the flow clearer.
5. Type-safe session metadata filters with
UnresolvedMetadataFilterThe
sessionMetadataFiltersparameter accepts JSON like{"branch":"main","developer":["Ellen","Sam"]}. Previously this was parsed toMap<String, Object>requiring@SuppressWarnings("unchecked")casts:Now we parse directly to an immutable domain record:
The record name documents the data flow: these filters have user-provided field names that must be resolved to numeric IDs before API calls.
How It Works
Status filtering - Before:
Status filtering - After:
Session metadata - Before:
Session metadata - After:
Step-by-Step Walkthrough
ExtendedTraceFilterBody.java- Simplified from 65 lines to 19 lineswithSessionFilters()factory methodstatusfield with Lombok@Getter/@SetterVulnerabilityFilterParams.java- ReturnsExtendedTraceFilterBodywith statustoTraceFilterBody()now returnsExtendedTraceFilterBodystatusfield usingSet.copyOf(statuses)for immutabilitySearchAppVulnerabilitiesParams.java- Same changes plus type-safe filtersExtendedTraceFilterBodywith statusMap<String, Object>toList<UnresolvedMetadataFilter>SearchAppVulnerabilitiesTool.java- Simplified session handlingwithSessionFilters()factoryagentSessionIdandmetadataFiltersdirectly on the filter bodynormalizeFilterValue()method and@SuppressWarningsresolveSessionMetadataFilters()now takesList<UnresolvedMetadataFilter>StringListSpec.java- Case-insensitive validation with normalizationallowedValues()now automatically matches case-insensitivelyreported→Reported)MetadataJsonFilterSpec.java- Returns domain typeget()returnsList<UnresolvedMetadataFilter>instead ofMap<String, Object>UnresolvedMetadataFilter.java- New domain recordTesting
ExtendedTraceFilterBody.statusfieldtoTraceFilterBody()returns correct type with statusUnresolvedMetadataFilterrecord validationMetadataJsonFilterSpecreturnsList<UnresolvedMetadataFilter>Files Changed
ExtendedTraceFilterBody.javastatusfieldSearchAppVulnerabilitiesTool.javaSearchAppVulnerabilitiesParams.javaExtendedTraceFilterBody, usesList<UnresolvedMetadataFilter>VulnerabilityFilterParams.javaExtendedTraceFilterBodywith statusStringListSpec.javaallowedValues()MetadataJsonFilterSpec.javaList<UnresolvedMetadataFilter>UnresolvedMetadataFilter.java