Skip to content

feat: Aviator apply-remediations issue-id filtering for SSC/FoD#1050

Open
kireetivar wants to merge 16 commits into
fortify:feat/v3.x/aviator/26.4from
kireetivar:p/kireetivar/filter_by_id
Open

feat: Aviator apply-remediations issue-id filtering for SSC/FoD#1050
kireetivar wants to merge 16 commits into
fortify:feat/v3.x/aviator/26.4from
kireetivar:p/kireetivar/filter_by_id

Conversation

@kireetivar

@kireetivar kireetivar commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Note: This PR will be merged into feat/v3.x/aviator/26.4

This PR adds remediations cache download/apply workflows for SSC and FoD so teams can download remediations once into a cache zip and apply them locally, including optional issue-level filtering.

What changed

  • Added new cache download commands:
    • fcli aviator ssc download-remediations-cache
    • fcli fod aviator download-remediations-cache
  • Extended existing apply commands:
    • fcli aviator ssc apply-remediations
    • fcli fod aviator apply-remediations
  • Added --from-cache support to SSC and FoD apply-remediations.
  • Added --issue-ids support for cache-based apply-remediations.
  • Added shared cache zip handling for manifest, entry ordering, checksum validation, reading, and writing.
  • Added SSC support for cache generation from:
    • --artifact-id
    • --latest
    • --all
  • Added FoD support for cache generation from:
    • --release / --rel
  • Added resilient handling for cache entries that do not contain remediations.xml.

Behavior

  • With --from-cache:
    • Apply-remediations reads FPRs from the cache zip in manifest order.
    • SSC and FoD process cached entries sequentially.
  • With --issue-ids:
    • Only remediations whose instanceId matches requested ids are considered.
    • --issue-ids is only supported together with --from-cache.
  • Without --issue-ids:
    • Existing apply-remediations behavior is unchanged for non-cache flows.
  • If a cached FPR does not contain remediations.xml:
    • The entry is skipped instead of failing the entire cache-based run.

SSC cache behavior

  • download-remediations-cache --all stores artifacts in chronological order.
  • apply-remediations --from-cache processes entries in the same stored order.
  • Output reports:
    • processed entries
    • skipped entries
    • processed artifact ids

FoD cache behavior

  • download-remediations-cache stores the selected release FPR in the cache zip.
  • apply-remediations --from-cache processes entries in cache order.
  • Output reports:
    • processed entries
    • processed release ids`

apply-remediations command additions

  • fcli aviator ssc apply-remediations --from-cache <zip>
  • fcli aviator ssc apply-remediations --from-cache <zip> --issue-ids <id1,id2,...>
  • fcli fod aviator apply-remediations --from-cache <zip>
  • fcli fod aviator apply-remediations --from-cache <zip> --issue-ids <id1,id2,...>

@kireetivar
kireetivar requested a review from rsenden July 6, 2026 08:58
@kireetivar kireetivar self-assigned this Jul 6, 2026

@rsenden rsenden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've done a partial review and added some individual code comments, which mostly originate from current (command) design. Can we improve the design, thereby automatically resolving most of these comments?

I think the key issue is that these commands operate on individual FPR files, thus requiring separate --file/--dir output options depending on how many FPRs are being downloaded, and deviating from fcli arity conventions to pass these FPRs through wildcards to apply-remediations commands. Also, when depending on user-specified dirs/wildcards, there's a risk that incorrect FPR files get picked up, for example from a previous run, possibly even from a different app version/release.

Three alternative approaches come to mind (but maybe you can think of other approaches):

  1. Get rid of download-remediations-fpr commands, and instead add caching options on apply-remediations commands, for example a --[no-]use-cache option that checks fcli state directory whether cached FPR files for current set of args (--av/--rel & artifact selection criteria) is available, downloading these to the cache on the fly if not yet available or outdated. Main complexity is cache management, for example requiring extra commands/options for updating or clearing cache, detecting outdated cache, ...
  2. Have download-remediations-fpr (possibly renamed to something like prepare-remediations-cache output a single 'remediations cache' zip file; depending on FPR selection criteria, this zip-file can contain either single or multiple FPR files, which users can then pass to apply-remediations cmd using --from-cache=<zip-file>
  3. Combination of the above; have apply-remediations --use-cache=<zip-file>; if given zip-file exists, it's used as is, otherwise it's created by downloading FPR files based on current FPR selection criteria. Possibly, the zip-file could contain metadata like app version/release and FPR selection criteria; if there's a mismatch with current selection criteria on the apply-remediations command, an error would be thrown.


@Override
public boolean isSingular() {
return true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What's the rationale for having singular output with artifact id's embedded in that single output record, rather than outputting separate records for every individual artifact? Unless there are good reasons against the latter, that's the more common fcli convention.

result.putArray("artifactIds").add(artifact.getId());
result.putArray("files").add(destination.toString());
result.put("file", destination.toString());
result.put(IActionCommandResultSupplier.actionFieldName, getActionCommandResult());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

fcli output framework automatically sets the 'action' column based on getActionCommandResult; explicitly setting this field is only necessary if you want to display dynamic action values, i.e., if that value depends on execution flow/result.

files.add(destination.toString());
artifactIds.add(artifact.getId());
}
result.put(IActionCommandResultSupplier.actionFieldName, getActionCommandResult());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

fcli output framework automatically sets the 'action' column based on getActionCommandResult; explicitly setting this field is only necessary if you want to display dynamic action values, i.e., if that value depends on execution flow/result.

throw new FcliSimpleException("--dir must be specified when using --all");
}
} else if (outputDir != null) {
throw new FcliSimpleException("--dir can only be used with --all; use -f/--file for a single FPR download");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is --dir not supported for single-file downloads, using the default FPR file name as defined in getSingleDestination.

private boolean latest;

@Option(names = {"--all"}, required = true, descriptionKey = "fcli.aviator.ssc.download-remediations-fpr.all")
private boolean allOpenIssues;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Weird field name for 'all FPRs'


@Option(names = {"--fpr"}, required = true, arity = "1..*", paramLabel = "<file>",
descriptionKey = "fcli.aviator.ssc.apply-remediations.fpr")
@DisableTest({TestType.MULTI_OPT_SPLIT, TestType.MULTI_OPT_PLURAL_NAME, TestType.OPT_ARITY_VARIABLE})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess the rationale for non-standard arity and the disabled tests is to allow this to work with wildcard patterns, i.e., --fpr /path/to/downloads/*.fpr? Although picocli does its best to handle multi-arity options, we encountered issues with this in the past, hence we usually disallow this.

return outputFile == null ? Path.of(String.format("remediations_artifact_%s.fpr", artifact.getId())) : outputFile.toPath();
}

private void validateDestinationOptions() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In general, I don't like exclusive sets of options as it affects user experience (difficult to figure out which sets of options can be combined), nor manual validation instead of picocli handling option exclusivity (also to properly display this in command syntax). Any way around this, by reorganizing ArgGroups?

@kireetivar

Copy link
Copy Markdown
Contributor Author

Thanks for the review comments. I’m planning to revise the PR away from the current raw-FPR workflow.

Proposed solution:

  • I am more inclined toward your option 2, with one explicit cache/archive file produced by the download command and consumed by apply.
  • Replace download-remediations-fpr with download-remediations-cache.
  • Remove the multi-arity --fpr option completely.
  • Use a single cache zip with manifest.json and ordered FPR entries.

Example manifest.json:

{
  "schemaVersion": 1,
  "kind": "aviator-remediations-cache",
  "product": "ssc",
  "createdAt": "2026-07-16T12:00:00Z",
  "selection": {
    "mode": "all",
    "appVersionId": "10001",
    "since": "2026-07-01T00:00:00Z"
  },
  "entries": [
    {
      "order": 1,
      "artifactId": "12345",
      "uploadDate": "2026-07-10T08:00:00Z",
      "path": "fprs/001_artifact_12345.fpr",
      "sha256": "8f14e45fceea167a5a36dedd4bea2543"
    },
    {
      "order": 2,
      "artifactId": "67890",
      "uploadDate": "2026-07-11T09:30:00Z",
      "path": "fprs/002_artifact_67890.fpr",
      "sha256": "45c48cce2e2d7fbdea1afc51c7c6ad26"
    }
  ]
}
  • Use --from-cache <zip> on apply-remediations, but not as a standalone source. The normal selection options are still required:
    • SSC: --artifact-id, or --latest/--all --av ...
    • FoD: --rel
  • If the cache exists, apply validates the manifest against the current selection. If it does not exist, the user should create it first with download-remediations-cache.
  • --issue-ids will require --from-cache, so filtered/partial applies do not repeatedly download from FoD/SSC.
  • The manifest will include product, server, selection metadata, ordered entries, upload dates, and required sha256; apply will verify checksums before modifying source.
  • Use the same --from-cache option name for SSC and FoD.

If you are ok with this proposal, I have a few questions I’d like your input on:

  1. Are the proposed option/command names OK: download-remediations-cache and --from-cache?
  2. Should --file be required for download-remediations-cache, or should we provide a deterministic default cache filename?
  3. Should download-remediations-cache overwrite existing files by default, fail by default, or require an explicit --overwrite option?
  4. If the selected SSC/FoD criteria resolve to zero matching artifacts, should we create an empty valid cache, or should cache download fail?

@rsenden

rsenden commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

I don't have a strong preference for either option 2 or 3:

  • Option 2 provides a more explicit split between creating the cache, and consuming the cache, but requires an extra command to be run
  • Option 3 allows for simply running the same command (with different issue id's) multiple times, automatically creating and consuming the cache as needed, but it may be slightly confusing that the --use-cache is used for both initial creation of the cache, and consuming it in subsequent runs

For option 2, I think it's better to have --from-cache being mutually exclusive with --av/--rel and artifact selection options; i.e., users either apply remediations from cache, or from the existing artifact selection options. This is more user-friendly (no need to repeat same options on download-remediations-cache and apply-remediations), and saves us from having to validate that apply-remediations options match the cache.

For option 3, we would need to verify options against cache, but then need to decide what to do if there's a mismatch; throw an error, replace the cache based on current selection options, ...

  1. Are the proposed option/command names OK: download-remediations-cache and --from-cache?

Yes, if we go for option 2

  1. Should --file be required for download-remediations-cache, or should we provide a deterministic default cache filename?

I think requiring --file is better, providing a clear link between download-remediations-cache and apply-remediations

  1. Should download-remediations-cache overwrite existing files by default, fail by default, or require an explicit --overwrite option?

Use CommonOptionMixins::RequireConfirmation mixin (see existing usages in fcli as example)

  1. If the selected SSC/FoD criteria resolve to zero matching artifacts, should we create an empty valid cache, or should cache download fail?

Not sure; probably should have same behavior as current non-cache based apply-remediations. Output should probably show the number of downloaded artifacts.

@kireetivar
kireetivar requested a review from rsenden July 17, 2026 11:20
try {
// ZipFS on sibling work file; existing destination is left intact until publish.
fs = ZipHelper.createZipFileSystem(workPath);
Files.createDirectories(fs.getPath(RemediationsCacheConstants.FPRS_DIR));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think state management in this class can be significantly simplified if directory creation is moved outside of the constructor:

  • Constructor just performs prerequisite ops/checks and then this.zipFs = ZipHelper.createZipFileSystem(workPath)
  • Any exceptions in constructor can be immediately thrown; no need to store error and check/handle elsewhere
  • No need to keep closed status, as close() would only need to be called by try-with-resources

public static RemediationsCacheWriter create(Path destination, String product, Map<String, String> selection) {
FcliSimpleException.throwIf(destination == null,
"-f/--file must specify a remediations cache zip path");
RemediationsCacheWriter writer = new RemediationsCacheWriter(destination, product, selection);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As an example of the simplification mentioned above, this code could be reduced to just a simple return new RemediationsCacheWriter(...);

RemediationsCacheWriter writer = new RemediationsCacheWriter(destination, product, selection);
if (writer.initError != null) {
Exception cause = writer.initError;
writer.close();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

With the mechanism described above, there's no need to explicitly call close(); either zipFs was successfully initialized (in which case it will be automatically closed by outer try-with-resources), or zipFs` initialization failed (in which case there's nothing to close)

* successful {@link #close()}.
* Returns the completed manifest.
*/
public RemediationsCacheManifest finish() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why have this as a separate public method that needs to be explicitly called? Why not just have the close() method automatically perform all finalization operations (but through separate private helper methods, to keep close() method fairly short)

}
}

private void requireWritable() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Based on comments above, I think there's little use for this method

}
}

public record FprSource(Path path, String artifactId, String releaseId, String uploadDate) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Having a single record that may represent two types of entities (SSC artifact id vs FoD release id) looks like a code smell; any way to improve?

* Source selection for apply-remediations: either online SSC selection or a local remediations cache zip.
*/
@Getter
public class AviatorSSCApplyRemediationsSourceMixin {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There seems to be quite some code duplication (like getter methods) between this class, AviatorSSCRemediationsCacheDownloadSelectorMixin, and possibly AviatorSSCRemediationsSelectorArgGroups ; any way to improve? Given that these classes are now by themselves responsible for resolving artifact descriptors, do we still need these accessors? If so, can we use @Getter (where appropriate) instead?

* Factory for writers (not Jackson). Avoids multi-arg same-type call sites on the wire model.
* Do not add {@code @Builder} on this {@code @Reflectable} class.
*/
public static RemediationsCacheEntry of(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Although it's an improvement to move this responsibility to the appropriate class:

  • Given the number of arguments, most with the same type, there's still the risk that arguments are passed in the wrong order
  • I don't like individual SSC and FoD properties being mixed in a single class; this makes it difficult to understand which properties are always required, and which properties are only applicable to either FoD or SSC

Before reading the below, please check the later comment about refactoring validation, as this is closely related and referenced in the proposals below.

A potentially better approach would be to have:

  • Separate RemediationsCacheFoDEntry and RemediationsCacheSSCEntry classes (please check correct case for FoD and SSC in these class names to be consistent with other fcli classes), each containing only the relevant properties for either FoD or SSC
  • Have both classes implement interface/abstract class that defines the shared properties like order, path, and sha256
  • If SSC/FoD-specific properties may not be null, add a validate method to each entry class
  • In RemediationsCacheManifest, declare two separate entry lists, i.e., fodEntries and sscEntries, or maybe keep single List<? extends ...> entries, deriving actual type from the product property

Alternatively, potentially easier from a caller perspective:

  • Keep a single RemediationsCacheEntry class, but introduce two (inner) model classes that represent FoD/SSC-specific properties
  • Introduce corresponding properties and accessors in this class, for example sscData and fodData (any better property names?)
  • Validation would require exactly one of these properties to be set
  • Validation of individual SSC/FoD-specific properties is done in the respective SSC/FoD-specific model classes
  • Instead of the single of method, introduce separate factory methods for SSC/FoD, each taking the SSC/FoD-specific model class (not individual properties), just assigning the provided model object to the sscData or fodData field
  • If useful, introduce factory methods on the SSC/FoD-specific model classes, like of(artifactId, ...) on the SSC model class, and of(releaseId, ...) on the FoD model class

}
}

private void validateManifest(RemediationsCacheManifest manifest) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think validation would be better moved to the model classes, i.e., this class would just check that manifest is not null, then call manifest.validate(cacheZip), which checks its own property values, then calls getEntries().forEach(e->e.validate(cacheZip)). This provides better encapsulation, reducing the risk of missing any validation checks, and based on the suggestion above about having different model classes for SSC/FoD, this would then also automatically allow SSC/FoD-specific properties to be validated.

return descriptor.getVersionId();
}

public String getSelectionMode() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I haven't checked whether the values produced by this method are only used in fcli output (in which case current implementation may be fine), or referenced/compared in any other code (in which case it would be better to use a proper enum)

.build());
}

private static ObjectNode toOnlineJson(OnlineResultData data) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Several observations/questions on this method and related methods/classes:

  • In general, we should attempt to have each fcli command output a consistent (sub)set of properties regardless of options/operating mode, for example to allow for proper, useful table output (even if that's not the default output format). Ideally, to ensure consistent output and allow for better code re-use, code/class structure should represent which properties are always being written (independent of operating mode), and what properties are only applicable to a certain operating mode, for example by moving shared properties to a common superclass that's inherited by both CacheResultData and OnlineResultData.
  • Given that these *ResultData classes are (primarily) meant to represent output properties, why are we manually constructing an ObjectNode instead of using Jackson serialization?
  • If Jackson serialization isn't possible for any reason, rendering JSON output should be the responsibility of the data class, i.e., having *ResultData::toJson methods, to provide better encapsulation and make it less likely (being closer to the actual property definitions) that any properties are missed.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR extends the Aviator remediation workflows to support generating a reusable “remediations cache” zip for both SSC and FoD, and adds cache-based apply flows that can optionally filter remediations by issue id(s). It also introduces shared cache-zip read/write/validation utilities and refactors the apply flows to use a common “iterate FPR sources + apply” loop for both online and offline sources.

Changes:

  • Added download-remediations-cache commands for SSC and FoD, producing an ordered zip (manifest + FPR entries + checksums).
  • Extended SSC/FoD apply-remediations to support --from-cache and optional --issue-ids filtering for cache-based runs.
  • Introduced shared cache utilities (ZipFS helpers, cache reader/writer, checksum validation, common apply loop) and improved temp FPR handling.

Reviewed changes

Copilot reviewed 47 out of 47 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
fcli-core/fcli-ssc/src/test/java/com/fortify/cli/ssc/artifact/helper/SSCArtifactHelperTest.java Adds unit tests for new Aviator artifact detection/validation logic.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/artifact/helper/SSCArtifactHelper.java Adds isAviatorArtifact()/requireAviatorArtifact() helpers used by SSC selection flows.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/ssc/transfer/SSCFileTransferHelper.java Adds Path-based download support for ZipFS destinations and safer write-on-ready behavior.
fcli-core/fcli-fod/src/test/java/com/fortify/cli/fod/aviator/FoDAviatorDownloadRemediationsCacheCommandTest.java Adds CLI parse/required-arg tests for FoD cache download command.
fcli-core/fcli-fod/src/test/java/com/fortify/cli/fod/aviator/FoDAviatorApplyRemediationsCommandTest.java Updates FoD apply-remediations tests for new source selection + issue-id rules.
fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties Documents new FoD cache and issue-id options and adds output table args for cache download.
fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/helper/FoDRemediationsFprDownloadHelper.java Adds FoD download helper with 202 retry + “write body only when ready” semantics.
fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/helper/FodOnlineRemediationsFprSource.java Implements online FoD FPR source that downloads to managed temp files per entry.
fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/helper/AviatorFoDApplyRemediationsHelper.java Refactors FoD apply output JSON building for both online and cache flows.
fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/cmd/FoDAviatorDownloadRemediationsCacheCommand.java Adds FoD download-remediations-cache command that writes a cache zip.
fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/cmd/FoDAviatorCommands.java Registers FoD download-cache subcommand.
fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/cmd/FoDAviatorApplyRemediationsCommand.java Adds FoD --from-cache and --issue-ids handling and splits online vs cache processing.
fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/aviator/cli/mixin/FoDAviatorApplyRemediationsSourceMixin.java Adds FoD apply source selector ArgGroup (release vs cache).
fcli-core/fcli-common-core/src/main/java/com/fortify/cli/common/util/ZipHelper.java Adds ZipFS open/create helpers used by cache reader/writer.
fcli-core/fcli-common-core/src/main/java/com/fortify/cli/common/exception/FcliSimpleException.java Adds FcliSimpleException.throwIf(...) guard helper for compact validations.
fcli-core/fcli-aviator/src/test/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCDownloadRemediationsCacheCommandTest.java Adds tests for SSC cache download CLI rules/validation behavior.
fcli-core/fcli-aviator/src/test/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCApplyRemediationsCommandTest.java Adds tests for SSC apply-remediations cache selection and issue-id rule.
fcli-core/fcli-aviator/src/main/resources/com/fortify/cli/aviator/i18n/AviatorMessages.properties Updates SSC help text and adds messages for cache download/apply and issue-id filtering.
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/SscOnlineRemediationsFprSource.java Implements online SSC FPR source that downloads each artifact to a temp file.
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCApplyRemediationsHelper.java Refactors SSC apply output JSON building for online and cache flows.
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/mixin/AviatorSSCRemediationsSelectorArgGroups.java Adds shared SSC online selection ArgGroups for both apply and cache-download commands.
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/mixin/AviatorSSCRemediationsCacheDownloadSelectorMixin.java Wraps shared SSC online selection group for cache download command.
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/mixin/AviatorSSCApplyRemediationsSourceMixin.java Adds SSC apply source selector (online vs cache).
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/mixin/AviatorSSCApplyRemediationsArtifactSelectorMixin.java Removes old apply selector mixin (replaced by shared selector + source mixin).
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCDownloadRemediationsCacheCommand.java Adds SSC download-remediations-cache command that writes a cache zip from artifacts.
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCCommands.java Registers SSC download-cache subcommand.
fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCApplyRemediationsCommand.java Adds SSC --from-cache + --issue-ids support and refactors apply loop into shared helper.
fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/fpr/processor/RemediationProcessorTest.java Adds tests for issue-id filtering behavior and path traversal resilience.
fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/_common/util/AviatorRemediationMetricsHelperTest.java Adds tests for aggregation semantics when issue-id filtering is enabled.
fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/_common/util/AviatorLocalFprHelperTest.java Adds tests for local FPR validation helper.
fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/_common/util/AviatorIssueIdFilterUtilsTest.java Adds tests for issue-id normalization + blank-value rejection.
fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheRoundTripTest.java Adds end-to-end cache zip writer/reader tests (order, checksums, path safety).
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/fpr/processor/RemediationProcessor.java Refactors remediation application logic and adds optional issue-id filtering metric tracking.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/applyRemediation/ApplyAutoRemediationOnSource.java Extends apply API to accept an optional issue-id filter set.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/util/AviatorTempFprFile.java Adds managed temp-file utility for online-download FPR staging.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/util/AviatorRemediationMetricsHelper.java Adds helper to aggregate metrics across entries and handle remaining issue-id logic.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/util/AviatorLocalFprHelper.java Adds helper for validating local on-disk FPR files before processing.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/util/AviatorIssueIdFilterUtils.java Adds normalization/deduplication and validation for issue-id filters.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheWriter.java Adds cache zip writer (ZipFS-based, ordered entries, manifest writing, publish-on-close).
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheSha256.java Adds SHA-256 helpers for cache entry integrity checks.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheReader.java Adds cache zip reader (manifest/schema validation, safe entry resolution, checksum validation).
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheManifest.java Adds manifest wire model for cache zip metadata.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheEntry.java Adds manifest entry model + factory method for writer-side creation.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsCacheConstants.java Adds cache schema/product constants shared across modules.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/RemediationsApplyHelper.java Adds shared apply loop that processes entries sequentially and soft-skips unsupported entries.
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/IRemediationsFprSource.java Adds common abstraction for “iterate FPR entries” (online or cache sources).
fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/_common/remediations_cache/CacheRemediationsFprSource.java Adds cache-backed implementation of IRemediationsFprSource using the cache reader.
Comments suppressed due to low confidence (1)

fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/ssc/transfer/SSCFileTransferHelper.java:63

  • The download(..., File downloadPath, ...) overload writes the response directly via asFile() and doesn’t perform the status/202 check or incomplete-download cleanup that the new Path-based overload provides. If the server returns a non-2xx/202 response, this can leave a partially written or error-body file on disk.

Comment on lines +100 to +103
// Log requested issue IDs that were not found in any remediation entries
for (String notFoundIssueId : processingState.getRequestedButNotApplied()) {
logger.debug("Requested issue ID '{}' was not found in any remediation entries in remediations.xml", notFoundIssueId);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants