diff --git a/ee/app/services/security/vulnerability_scanning/create_vulnerability_service.rb b/ee/app/services/security/vulnerability_scanning/create_vulnerability_service.rb index d0ca95f41a2deafd83e13aaf5c6239f2573fb668..63c4b482ee3c077541508dc5d0f030ee52d669ec 100644 --- a/ee/app/services/security/vulnerability_scanning/create_vulnerability_service.rb +++ b/ee/app/services/security/vulnerability_scanning/create_vulnerability_service.rb @@ -5,6 +5,8 @@ module VulnerabilityScanning class CreateVulnerabilityService include Gitlab::Utils::StrongMemoize + FINDINGS_LIMIT = 50 + PRE_CREATE_TASKS = %i[ reject_findings_maps_exceeding_quota ].freeze @@ -189,16 +191,19 @@ def projects strong_memoize_attr :projects def trigger_vulnerabilities_created_event - return unless finding_data.present? + return unless findings_for_vulnerabilities.present? - ::Gitlab::EventStore.publish(vulnerabilities_created_event) + findings_for_vulnerabilities.each_slice(FINDINGS_LIMIT) do |findings| + event = vulnerabilities_created_event(findings) + ::Gitlab::EventStore.publish(event) + end end - def vulnerabilities_created_event - Sbom::VulnerabilitiesCreatedEvent.new(data: { findings: finding_data }.with_indifferent_access) + def vulnerabilities_created_event(findings) + Sbom::VulnerabilitiesCreatedEvent.new(data: { findings: findings }.with_indifferent_access) end - def finding_data + def findings_for_vulnerabilities finding_maps.filter_map do |finding_map| next unless include_finding_map?(finding_map) @@ -212,7 +217,7 @@ def finding_data } end end - strong_memoize_attr :finding_data + strong_memoize_attr :findings_for_vulnerabilities def include_finding_map?(finding_map) finding_map.report_type == 'dependency_scanning' && diff --git a/ee/spec/services/security/vulnerability_scanning/create_vulnerability_service_spec.rb b/ee/spec/services/security/vulnerability_scanning/create_vulnerability_service_spec.rb index 13a39d6864b087b8593a9210307df3ab48ece8d1..b9b780977f8c966b898a2d83f19e14c821b63a42 100644 --- a/ee/spec/services/security/vulnerability_scanning/create_vulnerability_service_spec.rb +++ b/ee/spec/services/security/vulnerability_scanning/create_vulnerability_service_spec.rb @@ -112,6 +112,33 @@ }) end + context 'with a number of findings higher than `FINDINGS_LIMIT`' do + let(:security_finding_second) do + create(:ci_reports_security_finding, location: locations, report_type: report_type) + end + + let(:finding_map_second) do + create(:vs_finding_map, pipeline: pipeline, report_finding: security_finding_second, purl_type: purl_type) + end + + let(:finding_maps) { [finding_map, finding_map_second] } + + before do + stub_const("#{described_class}::FINDINGS_LIMIT", 1) + end + + it 'publishes a new event with findings based on `FINDINGS_LIMIT`' do + expect_next_instance_of(described_class) do |service| + expect(service).to receive(:vulnerabilities_created_event) + .with([hash_including(uuid: security_finding.uuid)]).and_call_original + expect(service).to receive(:vulnerabilities_created_event) + .with([hash_including(uuid: security_finding_second.uuid)]).and_call_original + end + + service_response + end + end + context 'with feature flag disabled' do before do stub_feature_flags(update_sbom_occurrences_vulnerabilities_on_cvs: false)