Extract V3SyncService from the malware sync service
What does this MR do and why?
This is a pure refactor with no behaviour change for the malware advisory caller.
It extracts PackageMetadata::V3SyncService as a base class from PackageMetadata::MalwareAdvisorySyncService. The logic being moved is generic to the v3 distribution contract, not specific to malware: instance-token pre-flight, /supported filtering, bulk /delta calls, and checkpointing. Licenses will need the same run shape. The malware class now only supplies dataset-specific hooks: data type, fabricator, ingestion service, offline connector, pacing budget and log event. Connector::Pds.for is also split so a token pre-flight can reach dataset token scope without building a connector.
The checkpoint scope is also generalized ahead of the licenses subclass. Checkpoint.for_malware_advisories filtered on data_type alone. It is now Checkpoint.for_dataset(data_type, version_format), matching how checkpoint rows are actually keyed: data_type + version_format + purl_type. For malware this is a no-op, since every malware checkpoint row is already v3. It matters for licenses, which also has v2 rows: without the version_format filter, a licenses v3 run could pick up a v2 row, inherit a v2 bookmark, skip the /all bootstrap, and advance the wrong row. validate_v3_configs! now raises if a non-v3 config reaches the service, guarding against that case.
What a new dataset inherits
- The run.
it_behaves_like 'a v3 sync service'gives a subclass the whole#execute/.executesuite: checkpoint advance, resume and interrupt, the/allsnapshot bootstrap, bulk-vs-individual routing,/supportedfiltering and the token pre-flight. Nothing is passed in — the shared examples read the dataset offdescribed_class. - The contract. Nine abstract hooks, each asserted in
v3_sync_service_spec.rb.log_eventis one of them, so a subclass has to state its own event string rather than inherit a derived one.
Evidence behaviour is preserved
- The malware spec runs the same 35 examples before and after its
#execute/.executeblocks moved into the shared examples. The assertions are unchanged; only the hard-coded malware literals becamedescribed_class-derived. - 93 examples green across the service, worker and checkpoint specs.
Note
The malware spec is down to 80 lines. Its run coverage now lives in ee/spec/support/shared_examples/services/package_metadata/v3_sync_service_shared_examples.rb, so licenses inherits it instead of copying the file. What stayed behind is malware-only: the pinned log strings and the offline purl_type guard.
References
Related issue: Add package metadata sync service for v3 versio... (#622511 - closed) • Igor Frenkel, Orin Naaman • 19.4
- Epic: Sync v3 licenses from PDS (Online sync) (&23153 - closed) • Orin Naaman • 19.4
- Connector split this mirrors: PDS connector abstraction (#611182 - closed) • Orin Naaman • 19.4
- Licenses v2-to-v3 switch: Switch the licenses sync from v2 to v3 + rollout (#606527 - closed) • Unassigned • 19.4
- Offline purl_type guard: Offline malware sync advances a registry's chec... (#613635 - closed) • Unassigned • 19.4