Skip to content

Commit 8ef84e3

Browse files
perf(importers): batch BurpRawRequestResponse inserts + re-enable perf tests (#14969)
* perf(importers): batch BurpRawRequestResponse inserts + re-enable perf tests Replace per-finding save() calls in process_request_response_pairs with bulk_create at batch boundaries, mirroring the location_handler pattern. Reduces DB round-trips proportionally to findings with req/resp data. Drops the no-op clean() calls (BurpRawRequestResponse has no custom clean). Re-enable TestDojoImporterPerformanceSmall and TestDojoImporterPerformanceSmallLocations with recalibrated query counts after the RBAC→legacy authorization migration. * test(perf): recalibrate tag inheritance ZAP query counts Batch BurpRawRequestResponse inserts reduce per-finding saves for the ZAP parser (which emits req/resp pairs). Update expected counts to match.
1 parent 5fd73ac commit 8ef84e3

4 files changed

Lines changed: 22 additions & 16 deletions

File tree

dojo/importers/base_importer.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def __init__(
8080
ImporterOptions.__init__(self, *args, **kwargs)
8181
self.pending_vulnerability_ids: list[Vulnerability_Id] = []
8282
self.pending_vuln_id_deletes: list[int] = []
83+
self.pending_burp_rr: list[BurpRawRequestResponse] = []
8384

8485
def check_child_implementation_exception(self):
8586
"""
@@ -719,24 +720,26 @@ def process_request_response_pairs(
719720
Create BurpRawRequestResponse objects linked to the finding without
720721
returning the finding afterward
721722
"""
722-
if len(unsaved_req_resp := getattr(finding, "unsaved_req_resp", [])) > 0:
723-
for req_resp in unsaved_req_resp:
724-
burp_rr = BurpRawRequestResponse(
725-
finding=finding,
726-
burpRequestBase64=base64.b64encode(req_resp["req"].encode("utf-8")),
727-
burpResponseBase64=base64.b64encode(req_resp["resp"].encode("utf-8")))
728-
burp_rr.clean()
729-
burp_rr.save()
723+
for req_resp in getattr(finding, "unsaved_req_resp", []):
724+
self.pending_burp_rr.append(BurpRawRequestResponse(
725+
finding=finding,
726+
burpRequestBase64=base64.b64encode(req_resp["req"].encode("utf-8")),
727+
burpResponseBase64=base64.b64encode(req_resp["resp"].encode("utf-8")),
728+
))
730729

731730
unsaved_request = getattr(finding, "unsaved_request", None)
732731
unsaved_response = getattr(finding, "unsaved_response", None)
733732
if unsaved_request is not None and unsaved_response is not None:
734-
burp_rr = BurpRawRequestResponse(
733+
self.pending_burp_rr.append(BurpRawRequestResponse(
735734
finding=finding,
736735
burpRequestBase64=base64.b64encode(unsaved_request.encode()),
737-
burpResponseBase64=base64.b64encode(unsaved_response.encode()))
738-
burp_rr.clean()
739-
burp_rr.save()
736+
burpResponseBase64=base64.b64encode(unsaved_response.encode()),
737+
))
738+
739+
def flush_burp_request_response(self) -> None:
740+
if self.pending_burp_rr:
741+
BurpRawRequestResponse.objects.bulk_create(self.pending_burp_rr, batch_size=1000)
742+
self.pending_burp_rr.clear()
740743

741744
def process_locations(
742745
self,

dojo/importers/default_importer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ def _process_findings_internal(
276276
if len(batch_finding_ids) >= batch_max_size or is_final_finding:
277277
self.location_handler.persist()
278278
self.flush_vulnerability_ids()
279+
self.flush_burp_request_response()
279280
# Apply parser-supplied tags for this batch before post-processing starts,
280281
# so rules/deduplication tasks see the tags already on the findings.
281282
bulk_apply_parser_tags(findings_with_parser_tags)

dojo/importers/default_reimporter.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ def _process_findings_internal(
440440
if len(batch_finding_ids) >= dedupe_batch_max_size or is_final:
441441
self.location_handler.persist()
442442
self.flush_vulnerability_ids()
443+
self.flush_burp_request_response()
443444
# Apply parser-supplied tags for this batch before post-processing starts,
444445
# so rules/deduplication tasks see the tags already on the findings.
445446
bulk_apply_parser_tags(findings_with_parser_tags)
@@ -564,6 +565,7 @@ def close_old_findings(
564565
# Persist any accumulated location/endpoint status changes
565566
self.location_handler.persist()
566567
self.flush_vulnerability_ids()
568+
self.flush_burp_request_response()
567569
# push finding groups to jira since we only only want to push whole groups
568570
# We dont check if the finding jira sync is applicable quite yet until we can get in the loop
569571
# but this is a way to at least make it that far

unittests/test_tag_inheritance_perf.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -590,9 +590,9 @@ def test_baseline_zap_scan_reimport_with_new_findings_v3(self):
590590
# the async watson indexer, executed inline under CELERY_TASK_ALWAYS_EAGER);
591591
# +5 reimport (no-change + with-new) queries from removal of
592592
# WATSON_ASYNC_INDEX_UPDATE_THRESHOLD making async dispatch unconditional.
593-
EXPECTED_ZAP_IMPORT_V2 = 368
594-
EXPECTED_ZAP_IMPORT_V3 = 392
593+
EXPECTED_ZAP_IMPORT_V2 = 287
594+
EXPECTED_ZAP_IMPORT_V3 = 311
595595
EXPECTED_ZAP_REIMPORT_NO_CHANGE_V2 = 74
596596
EXPECTED_ZAP_REIMPORT_NO_CHANGE_V3 = 86
597-
EXPECTED_ZAP_REIMPORT_WITH_NEW_V2 = 170
598-
EXPECTED_ZAP_REIMPORT_WITH_NEW_V3 = 199
597+
EXPECTED_ZAP_REIMPORT_WITH_NEW_V2 = 148
598+
EXPECTED_ZAP_REIMPORT_WITH_NEW_V3 = 177

0 commit comments

Comments
 (0)