diff --git a/fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/fpr/model/FPRInfo.java b/fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/fpr/model/FPRInfo.java
index 650f5d92e1..3ad0db1243 100644
--- a/fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/fpr/model/FPRInfo.java
+++ b/fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/fpr/model/FPRInfo.java
@@ -52,6 +52,7 @@ public class FPRInfo {
public FPRInfo(FprHandle fprHandle) {
FPRName = String.valueOf(fprHandle.getFprPath().getFileName());
+ buildId = "";
try {
extractInfoFromAuditFvdlStreaming(fprHandle);
} catch (Exception e) {
@@ -151,6 +152,10 @@ private void extractInfoFromAuditFvdlStreaming(FprHandle fprHandle) throws Excep
} catch (javax.xml.stream.XMLStreamException e) {
throw new Exception("Failed to parse audit.fvdl using streaming parser", e);
}
+
+ if (buildId == null) {
+ buildId = "";
+ }
}
/**
diff --git a/fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/grpc/AviatorStreamProcessor.java b/fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/grpc/AviatorStreamProcessor.java
index 8f89f10183..1a42a6fec4 100644
--- a/fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/grpc/AviatorStreamProcessor.java
+++ b/fcli-core/fcli-aviator-common/src/main/java/com/fortify/cli/aviator/grpc/AviatorStreamProcessor.java
@@ -52,6 +52,7 @@
import com.fortify.cli.aviator.util.FileTypeLanguageMapperUtil;
import com.fortify.cli.aviator.util.FileUtil;
import com.fortify.cli.aviator.util.FprHandle;
+import com.fortify.cli.aviator.util.StringUtil;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
@@ -488,19 +489,23 @@ public void onCompleted() {
private void sendInitRequest() throws Exception {
String initRequestId = UUID.randomUUID().toString();
+ StreamInitRequest.Builder initRequestBuilder = StreamInitRequest.newBuilder()
+ .setStreamId(currentStreamState.streamId)
+ .setRequestId(initRequestId)
+ .setToken(currentStreamState.token)
+ .setApplicationName(currentStreamState.projectName)
+ .setSscApplicationName(currentStreamState.SSCApplicationName)
+ .setSscApplicationVersion(currentStreamState.SSCApplicationVersion)
+ .setTotalReportedIssues(currentStreamState.totalRequests)
+ .setTotalIssuesToPredict(currentStreamState.totalRequests);
+
+ if (!StringUtil.isEmpty(currentStreamState.FPRBuildId)) {
+ initRequestBuilder.setFprBuildId(currentStreamState.FPRBuildId);
+ }
+
UserPromptRequest initRequest = UserPromptRequest.newBuilder()
- .setInit(StreamInitRequest.newBuilder()
- .setStreamId(currentStreamState.streamId)
- .setRequestId(initRequestId)
- .setToken(currentStreamState.token)
- .setApplicationName(currentStreamState.projectName)
- .setSscApplicationName(currentStreamState.SSCApplicationName)
- .setSscApplicationVersion(currentStreamState.SSCApplicationVersion)
- .setFprBuildId(currentStreamState.FPRBuildId)
- .setTotalReportedIssues(currentStreamState.totalRequests)
- .setTotalIssuesToPredict(currentStreamState.totalRequests)
- .build())
- .build();
+ .setInit(initRequestBuilder.build())
+ .build();
requestHandler.sendRequest(initRequest);
LOG.info("Client Id for stream initialization {}", currentStreamState.streamId);
diff --git a/fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/audit/IssueAuditorTest.java b/fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/audit/IssueAuditorTest.java
index 79a2c5b4ec..cee9ef7e6b 100644
--- a/fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/audit/IssueAuditorTest.java
+++ b/fcli-core/fcli-aviator-common/src/test/java/com/fortify/cli/aviator/audit/IssueAuditorTest.java
@@ -81,6 +81,37 @@ void tearDown() throws IOException {
}
}
+ @Test
+ void testFprInfoMissingBuildIdDefaultsToEmptyString() throws Exception {
+ if (fprHandle != null) {
+ fprHandle.close();
+ fprHandle = null;
+ }
+ if (tempFprFile != null) {
+ Files.deleteIfExists(tempFprFile);
+ }
+
+ tempFprFile = Files.createTempFile("test_aviator_missing_build", ".fpr");
+ try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(tempFprFile))) {
+ ZipEntry entry = new ZipEntry("audit.fvdl");
+ zos.putNextEntry(entry);
+ String minimalXml = "test-uuid";
+ zos.write(minimalXml.getBytes(StandardCharsets.UTF_8));
+ zos.closeEntry();
+
+ ZipEntry indexEntry = new ZipEntry("src-archive/index.xml");
+ zos.putNextEntry(indexEntry);
+ String indexXml = "";
+ zos.write(indexXml.getBytes(StandardCharsets.UTF_8));
+ zos.closeEntry();
+ }
+
+ fprHandle = new FprHandle(tempFprFile);
+ FPRInfo fprInfo = new FPRInfo(fprHandle);
+
+ assertEquals("", fprInfo.getBuildId());
+ }
+
@Test
void testFilterVulnerabilities_LegacySyntaxWithSpaces() throws Exception {
diff --git a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCAuditHelper.java b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCAuditHelper.java
index 93fe7278e2..df21a6b07c 100644
--- a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCAuditHelper.java
+++ b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCAuditHelper.java
@@ -196,28 +196,33 @@ public static String getProgressMessage(FPRAuditResult auditResult) {
public static long getAuditableIssueCount(UnirestInstance unirest, SSCAppVersionDescriptor av, AviatorLoggerImpl logger, boolean noFilterSet, SSCIssueFilterSetOptionMixin filterSetOptions, List folderNames) {
logger.progress("Status: Checking for auditable issues...");
- GetRequest request = unirest.get(SSCUrls.PROJECT_VERSION_ISSUES(av.getVersionId()))
- .queryString("limit", PAGE_LIMIT)
- .queryString("embed", "auditValues")
- .queryString("qm", "issues")
- .queryString("q", "audited:false");
+ LOG.debug("Starting auditable issue count for SSC version {} (application='{}', version='{}') with pageLimit={}, noFilterSet={}",
+ av.getVersionId(), av.getApplicationName(), av.getVersionName(), PAGE_LIMIT, noFilterSet);
// Apply filter set if specified
SSCIssueFilterSetDescriptor filterSetDescriptor = null;
+ String filterSetGuid = null;
if (!noFilterSet) {
SSCIssueFilterSetHelper filterSetHelper = new SSCIssueFilterSetHelper(unirest, av.getVersionId());
filterSetDescriptor = filterSetHelper.getDescriptorByTitleOrId(filterSetOptions.getFilterSetTitleOrId(), false);
if (filterSetDescriptor != null) {
logger.progress("Status: Applying filter set '%s' for issue count check", filterSetDescriptor.getTitle());
- request.queryString("filterset", filterSetDescriptor.getGuid());
+ filterSetGuid = filterSetDescriptor.getGuid();
+ LOG.debug("Applied SSC filter set '{}' with guid {} while counting auditable issues for version {}",
+ filterSetDescriptor.getTitle(), filterSetGuid, av.getVersionId());
+ } else {
+ LOG.debug("No SSC filter set resolved from options while counting auditable issues for version {}",
+ av.getVersionId());
}
}
// Apply folder filter if specified
+ String folderFilter = null;
if (folderNames != null && !folderNames.isEmpty()) {
- String folderFilter = getFolderFilter(noFilterSet, filterSetDescriptor, folderNames);
- request.queryString("filter", folderFilter);
+ folderFilter = getFolderFilter(noFilterSet, filterSetDescriptor, folderNames);
logger.progress("Status: Applying folder filter for: %s", String.join(", ", folderNames));
+ LOG.debug("Applied folder filter '{}' for folders {} while counting auditable issues for version {}",
+ folderFilter, folderNames, av.getVersionId());
}
long totalAuditableCount = 0;
@@ -226,7 +231,21 @@ public static long getAuditableIssueCount(UnirestInstance unirest, SSCAppVersion
try {
do {
- JsonNode response = request.queryString("start", start).asObject(JsonNode.class).getBody();
+ GetRequest request = unirest.get(SSCUrls.PROJECT_VERSION_ISSUES(av.getVersionId()))
+ .queryString("limit", PAGE_LIMIT)
+ .queryString("embed", "auditValues")
+ .queryString("qm", "issues")
+ .queryString("q", "audited:false")
+ .queryString("start", start);
+ if (filterSetGuid != null) {
+ request.queryString("filterset", filterSetGuid);
+ }
+ if (folderFilter != null) {
+ request.queryString("filter", folderFilter);
+ }
+ LOG.debug("Requesting SSC issues page for version {} with start={} and limit={}",
+ av.getVersionId(), start, PAGE_LIMIT);
+ JsonNode response = request.asObject(JsonNode.class).getBody();
if (response == null || !response.has("data")) {
LOG.warn("Invalid response received from issue check; proceeding with FPR download.");
logger.progress("WARN: Invalid response from issue check. Proceeding with FPR download.");
@@ -234,6 +253,8 @@ public static long getAuditableIssueCount(UnirestInstance unirest, SSCAppVersion
}
if (totalFromServer == -1) {
totalFromServer = response.get("count").asLong(0);
+ LOG.debug("SSC reported {} total issues matching the initial auditable count query for version {}",
+ totalFromServer, av.getVersionId());
}
ArrayNode issues = (ArrayNode) response.get("data");
@@ -242,12 +263,18 @@ public static long getAuditableIssueCount(UnirestInstance unirest, SSCAppVersion
.filter(issue -> !isProcessedByAviator(issue))
.count();
totalAuditableCount += auditableOnPage;
+ LOG.debug("Processed SSC issues page for version {}: pageStart={}, pageSize={}, auditableOnPage={}, cumulativeAuditableCount={}, totalFromServer={}",
+ av.getVersionId(), start, issues.size(), auditableOnPage, totalAuditableCount, totalFromServer);
start += issues.size();
} else {
+ LOG.debug("SSC returned no more issues for version {} at start={}; stopping pagination with cumulativeAuditableCount={} and totalFromServer={}",
+ av.getVersionId(), start, totalAuditableCount, totalFromServer);
break; // No more issues
}
} while (start < totalFromServer);
+ LOG.debug("Completed auditable issue count for version {}: totalAuditableCount={}, totalFromServer={}",
+ av.getVersionId(), totalAuditableCount, totalFromServer);
logger.progress("Status: Found %d auditable issues.", totalAuditableCount);
return totalAuditableCount;
} catch (UnexpectedHttpResponseException e) {